{"record":{"id":"14f5ba52eb70d89d","repo":"hashicorp/nomad","slug":"hash-check-failed-for-q","errorCode":null,"errorMessage":"hash check failed for %q","messagePattern":"hash check failed for %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/snapshot/archive.go","lineNumber":81,"sourceCode":"// DecodeAndVerify reads a SHA256SUMS-style text file and checks the results\n// against the current sums for all the hashes.\nfunc (hl *hashList) DecodeAndVerify(r io.Reader) error {\n\t// Read the file and make sure everything in there has a matching hash.\n\tseen := make(map[string]struct{})\n\ts := bufio.NewScanner(r)\n\tfor s.Scan() {\n\t\tsha := make([]byte, sha256.Size)\n\t\tvar file string\n\t\tif _, err := fmt.Sscanf(s.Text(), \"%x  %s\", &sha, &file); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\th, ok := hl.hashes[file]\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"list missing hash for %q\", file)\n\t\t}\n\t\tif !bytes.Equal(sha, h.Sum([]byte{})) {\n\t\t\treturn fmt.Errorf(\"hash check failed for %q\", file)\n\t\t}\n\t\tseen[file] = struct{}{}\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn err\n\t}\n\n\t// Make sure everything we had a hash for was seen.\n\tfor file := range hl.hashes {\n\t\tif _, ok := seen[file]; !ok {\n\t\t\treturn fmt.Errorf(\"file missing for %q\", file)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// write takes a writer and creates an archive with the snapshot metadata,","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/snapshot/archive.go#L63-L99","documentation":"DecodeAndVerify walks the SHA256SUMS listing inside a snapshot archive and compares each recorded hash against the hash of the data actually read from the archive. This error means the computed SHA256 of an entry does not match the hash listed in SHA256SUMS. The library throws it to guarantee snapshot integrity before a restore proceeds.","triggerScenarios":"The archive contents were modified/corrupted after writing, the writer mis-sized a tar entry (Size mismatch so bytes shift between entries), or a non-standard tool rewrote the tar changing byte order/content while keeping entries.","commonSituations":"Manual editing or repacking of a .snap archive, truncation from a failed upload/download, disk corruption, or writing state.bin with a size differing from metadata.Size.","solutions":["Recreate the snapshot with write() instead of hand-editing the archive","Verify the transfer checksum of the whole snapshot file (e.g. compare sha256 of the file before/after copy)","Ensure tar entry Sizes exactly match content length (metadata.Size for state.bin)","Check storage/disk for corruption; re-copy from a trusted source"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"sum, err := os.ReadFile(\"SHA256SUMS\")\nfileSum, err := sha256sumFile(snapshotPath)\nif err != nil || !bytes.Equal(sum, fileSum) {\n    return errors.New(\"snapshot archive corrupted; re-transfer\")\n}","typeGuard":null,"tryCatchPattern":"if err := snapshot.DecodeAndVerify(w, r, size); err != nil {\n    if strings.Contains(err.Error(), \"hash check failed\") {\n        // treat as corruption: discard and re-acquire snapshot\n    }\n    return err\n}","preventionTips":["Never edit or repack snapshot archives by hand","Verify end-to-end file checksum after any transfer","Keep the tar entry sizes exactly equal to the written bytes"],"tags":["integrity","hash-mismatch","snapshot"],"backgroundTag":"checksum-mismatch","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}