Index: /trunk/psModules/src/config/pmConfigMask.c
===================================================================
--- /trunk/psModules/src/config/pmConfigMask.c	(revision 18604)
+++ /trunk/psModules/src/config/pmConfigMask.c	(revision 18605)
@@ -64,11 +64,18 @@
 
     bool status = false;
-    char namekey[80];
-    char valuekey[80];
-
-    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe
-    if (!recipe) {
-        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe.");
-        return false;
+
+    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, "MASKS"); // The recipe
+    if (!recipe) {
+        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find MASKS recipe.");
+        return false;
+    }
+
+    // MASK.VALUE and MARK.VALUE aren't usually set in the recipe, but may be set in the header: create fake
+    // versions so that it won't complain later
+    if (!psMetadataLookup(recipe, "MASK.VALUE")) {
+        psMetadataAddU8(recipe, PS_LIST_TAIL, "MASK.VALUE", 0, "Bits to mask", 0);
+    }
+    if (!psMetadataLookup(recipe, "MARK.VALUE")) {
+        psMetadataAddU8(recipe, PS_LIST_TAIL, "MARK.VALUE", 0, "Bits for marking", 0);
     }
 
@@ -79,22 +86,52 @@
     }
 
+    char namekey[80];                   // Keyword name for symbolic name of mask entry
+    char valuekey[80];                  // Keyword name for value of mask entry
     for (int i = 0; i < nMask; i++) {
-
         snprintf(namekey,  64, "MSKNAM%02d", i);
         snprintf(valuekey, 64, "MSKVAL%02d", i);
 
         char *name = psMetadataLookupStr(&status, header, namekey);
+        if (!status || !name) {
+            psWarning("Unable to find header keyword %s when parsing mask", namekey);
+            continue;
+        }
         psU8 bit = psMetadataLookupU8(&status, header, valuekey);
+        if (!status) {
+            psWarning("Unable to find header keyword %s when parsing mask", namekey);
+            continue;
+        }
 
         // XXX validate that bit is a 2^n value?
 
-        psMetadataItem *item = psMetadataLookup(recipe, name);
+        psString nameAlready = NULL;    // Name of key with ".ALREADY" added
+        psStringAppend(&nameAlready, "%s.ALREADY", name);
+        bool already = psMetadataLookupBool(&status, recipe, nameAlready); // Already read this one?
+
+        psMetadataItem *item = psMetadataLookup(recipe, name); // Item in recipe with current value
+        if (item->type != PS_TYPE_MASK) {
+            psWarning("Mask recipe entry is not of a mask type (%x)", item->type);
+            item->type = PS_TYPE_MASK;
+        }
+
+        if (already) {
+            if (item && item->data.U8 != bit) {
+                psWarning("New mask recipe entry doesn't match previously loaded entry: %x vs %x",
+                          bit, item->data.U8);
+            }
+        } else {
+            psMetadataAddBool(recipe, PS_LIST_TAIL, nameAlready, 0, "Already read this mask value", true);
+        }
+
         if (!item) {
-            psWarning("mask recipe entry %s not in recipe\n", name);
-            psMetadataAddU8 (recipe, PS_LIST_TAIL, name, 0, "Bitmask bit value", bit);
+            psWarning("Mask recipe entry %s not in recipe\n", name);
+            psMetadataAddU8(recipe, PS_LIST_TAIL, name, 0, "Bitmask bit value", bit);
         } else {
             item->data.U8 = bit;
         }
-    }
+
+        psFree(nameAlready);
+    }
+
 
     return true;
