hashicorp/nomad · error
list missing hash for %q
Error message
list missing hash for %q
What it means
DecodeAndVerify parses a SHA256SUMS-style manifest from a snapshot archive and checks each listed file's hash against hashes the reader has been accumulating via hashList.Add. This error means the manifest lists a file that the code never registered a hash for — the archive's SHA256SUMS references content that doesn't belong to the expected snapshot layout (meta.json, state.bin).
Source
Thrown at helper/snapshot/archive.go:78
return nil
}
// DecodeAndVerify reads a SHA256SUMS-style text file and checks the results
// against the current sums for all the hashes.
func (hl *hashList) DecodeAndVerify(r io.Reader) error {
// Read the file and make sure everything in there has a matching hash.
seen := make(map[string]struct{})
s := bufio.NewScanner(r)
for s.Scan() {
sha := make([]byte, sha256.Size)
var file string
if _, err := fmt.Sscanf(s.Text(), "%x %s", &sha, &file); err != nil {
return err
}
h, ok := hl.hashes[file]
if !ok {
return fmt.Errorf("list missing hash for %q", file)
}
if !bytes.Equal(sha, h.Sum([]byte{})) {
return fmt.Errorf("hash check failed for %q", file)
}
seen[file] = struct{}{}
}
if err := s.Err(); err != nil {
return err
}
// Make sure everything we had a hash for was seen.
for file := range hl.hashes {
if _, ok := seen[file]; !ok {
return fmt.Errorf("file missing for %q", file)
}
}
return nilView on GitHub (pinned to 482b49bf1a)
Solutions
- Take a fresh snapshot with `nomad snapshot save` and restore from that archive instead of the failing one.
- Inspect the archive (`tar -tf <snap>` plus extracting SHA256SUMS) and compare listed files against the expected meta.json/state.bin set; discard archives with unexpected entries.
- Verify the archive's integrity/provenance — if SHA256SUMS was edited or the archive spliced, do not trust it.
- Re-download or re-copy the snapshot (checksum the transfer) if corruption during transfer is suspected.
- If this happens on archives your own tooling produces, ensure every file written into the tar is registered with hashList.Add before Encode.
Example fix
// before: verifying an untrusted/foreign manifest directly
hl := newHashList()
hl.Add("meta.json"); hl.Add("state.bin")
err := hl.DecodeAndVerify(sumsReader) // fails: unknown file in list
// after: prefer a freshly taken snapshot archive
// nomad snapshot save backup.snap
err := snapshot.LoadArchive(freshSnapshotFile) Defensive patterns
Strategy: validation
Validate before calling
// before decoding, sanity-check that the archive's manifest only
// contains the expected files
tr := tar.NewReader(f)
for {
hdr, err := tr.Next()
if err == io.EOF { break }
if err != nil { return err }
switch hdr.Name {
case "meta.json", "state.bin", "SHA256SUMS":
default:
return fmt.Errorf("unexpected file in snapshot archive: %s", hdr.Name)
}
} Try / catch
err := hl.DecodeAndVerify(r)
if err != nil {
if strings.Contains(err.Error(), "list missing hash for") {
return fmt.Errorf("snapshot archive manifest references unknown files; archive is not a valid Nomad snapshot: %w", err)
}
return err
} Prevention
- Only restore snapshots produced by `nomad snapshot save`.
- Never hand-edit or splice snapshot tarballs or SHA256SUMS.
- Checksum snapshot files after transfer and before restoring.
- When writing archives with hashList, register every file via Add before Encode.
When it happens
Trigger: Calling DecodeAndVerify (via read, when loading a snapshot archive) where the SHA256SUMS stream contains a line naming a file that was not passed to hl.Add — e.g. an archive with extra entries listed in SHA256SUMS, a manifest from a different archive, or a manifest tampered/replaced with foreign file names.
Common situations: Hand-edited or spliced snapshot tarballs; an archive produced by a different tool or Nomad version with extra files listed in SHA256SUMS; partially extracted/rebuilt archives where SHA256SUMS was kept but content files changed; corrupted download where the manifest survived but the expected file set differs.
Related errors
- hash check failed for %q
- file missing for %q
- failed checking integrity of snapshot: %v
- volume snapshot ID cannot be updated
- missing VolumeID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/83fef55f731e6cc4.
Report an issue: GitHub.