--- a/avr.c
+++ b/avr.c
@@ -1058,6 +1058,30 @@ int avr_signature(PROGRAMMER * pgm, AVRP
   return 0;
 }
 
+static uint8_t get_fuse_bitmask(AVRMEM * m) {
+  uint8_t bitmask_r = 0;
+  uint8_t bitmask_w = 0;
+  int i;
+
+  if (!m || m->size > 1) {
+    // not a fuse, compare bytes directly
+    return 0xFF;
+  }
+
+  // For fuses, only compare bytes that are actually written *and* read.
+  for (i=0; i<32; i++) {
+    if (m->op[AVR_OP_WRITE]->bit[i].type == AVR_CMDBIT_INPUT)
+      bitmask_w |= (1 << m->op[AVR_OP_WRITE]->bit[i].bitno);
+    if (m->op[AVR_OP_READ]->bit[i].type == AVR_CMDBIT_OUTPUT)
+      bitmask_r |= (1 << m->op[AVR_OP_READ]->bit[i].bitno);
+  }
+  return bitmask_r & bitmask_w;
+}
+
+int compare_memory_masked(AVRMEM * m, unsigned char buf1, unsigned char buf2) {
+  uint8_t bitmask = get_fuse_bitmask(m);
+  return ((buf1 & bitmask) != (buf2 & bitmask));
+}
 
 /*
  * Verify the memory buffer of p with that of v.  The byte range of v,
@@ -1104,11 +1128,30 @@ int avr_verify(AVRPART * p, AVRPART * v,
   for (i=0; i<size; i++) {
     if ((b->tags[i] & TAG_ALLOCATED) != 0 &&
         buf1[i] != buf2[i]) {
-      avrdude_message(MSG_INFO, "%s: verification error, first mismatch at byte 0x%04x\n"
-                      "%s0x%02x != 0x%02x\n",
-                      progname, i,
-                      progbuf, buf1[i], buf2[i]);
-      return -1;
+      uint8_t bitmask = get_fuse_bitmask(a);
+      if((buf1[i] & bitmask) != (buf2[i] & bitmask)) {
+        // Mismatch is not just in unused bits
+        avrdude_message(MSG_INFO, "%s: verification error, first mismatch at byte 0x%04x\n"
+                        "%s0x%02x != 0x%02x\n",
+                        progname, i,
+                        progbuf, buf1[i], buf2[i]);
+        return -1;
+      } else {
+        // Mismatch is only in unused bits
+        if ((buf1[i] | bitmask) != 0xff) {
+          // Programmer returned unused bits as 0, must be the part/programmer
+          avrdude_message(MSG_INFO, "%s: WARNING: ignoring mismatch in unused bits of \"%s\"\n"
+                          "%s(0x%02x != 0x%02x). To prevent this warning fix the part\n"
+                          "%sor programmer definition in the config file.\n",
+                          progname, memtype, progbuf, buf1[i], buf2[i], progbuf);
+        } else {
+          // Programmer returned unused bits as 1, must be the user
+          avrdude_message(MSG_INFO, "%s: WARNING: ignoring mismatch in unused bits of \"%s\"\n"
+                          "%s(0x%02x != 0x%02x). To prevent this warning set unused bits\n"
+                          "%sto 1 when writing (double check with your datasheet first).\n",
+                          progname, memtype, progbuf, buf1[i], buf2[i], progbuf);
+        }
+      }
     }
   }
 
--- a/libavrdude.h
+++ b/libavrdude.h
@@ -337,6 +337,9 @@ typedef void (*walk_avrparts_cb)(const c
                                  void *cookie);
 void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie);
 void sort_avrparts(LISTID avrparts);
+
+int compare_memory_masked(AVRMEM * m, unsigned char buf1, unsigned char buf2);
+
 #ifdef __cplusplus
 }
 #endif
--- a/main.c
+++ b/main.c
@@ -1264,8 +1264,11 @@ int main(int argc, char * argv [])
       }
     }
     
+    AVRMEM * m;
+    
     /* Now check what fuses are against what they should be */
-    if (safemodeafter_fuse != safemode_fuse) {
+    m = avr_locate_mem(p, "fuse");
+    if (compare_memory_masked(m, safemodeafter_fuse, safemode_fuse)) {
       fuses_updated = 1;
       avrdude_message(MSG_INFO, "%s: safemode: fuse changed! Was %x, and is now %x\n",
               progname, safemode_fuse, safemodeafter_fuse);
@@ -1293,7 +1296,8 @@ int main(int argc, char * argv [])
     }
 
     /* Now check what fuses are against what they should be */
-    if (safemodeafter_lfuse != safemode_lfuse) {
+    m = avr_locate_mem(p, "lfuse");
+    if (compare_memory_masked(m, safemodeafter_lfuse, safemode_lfuse)) {
       fuses_updated = 1;
       avrdude_message(MSG_INFO, "%s: safemode: lfuse changed! Was %x, and is now %x\n",
               progname, safemode_lfuse, safemodeafter_lfuse);
@@ -1321,7 +1325,8 @@ int main(int argc, char * argv [])
     }
 
     /* Now check what fuses are against what they should be */
-    if (safemodeafter_hfuse != safemode_hfuse) {
+    m = avr_locate_mem(p, "hfuse");
+    if (compare_memory_masked(m, safemodeafter_hfuse, safemode_hfuse)) {
       fuses_updated = 1;
       avrdude_message(MSG_INFO, "%s: safemode: hfuse changed! Was %x, and is now %x\n",
               progname, safemode_hfuse, safemodeafter_hfuse);
@@ -1346,7 +1351,8 @@ int main(int argc, char * argv [])
     }
 
     /* Now check what fuses are against what they should be */
-    if (safemodeafter_efuse != safemode_efuse) {
+    m = avr_locate_mem(p, "efuse");
+    if (compare_memory_masked(m, safemodeafter_efuse, safemode_efuse)) {
       fuses_updated = 1;
       avrdude_message(MSG_INFO, "%s: safemode: efuse changed! Was %x, and is now %x\n",
               progname, safemode_efuse, safemodeafter_efuse);
@@ -1374,7 +1380,7 @@ int main(int argc, char * argv [])
       avrdude_message(MSG_INFO, "%s: safemode: ", progname);
       if (failures == 0) {
         avrdude_message(MSG_INFO, "Fuses OK (E:%02X, H:%02X, L:%02X)\n",
-                safemode_efuse, safemode_hfuse, safemode_lfuse);
+                safemodeafter_efuse, safemodeafter_hfuse, safemodeafter_lfuse);
       }
       else {
         avrdude_message(MSG_INFO, "Fuses not recovered, sorry\n");
