{"record":{"id":"4706967b5d70c4e7","repo":"golang/go","slug":"crypto-sha256-invalid-hash-state-identifier","errorCode":null,"errorMessage":"crypto/sha256: invalid hash state identifier","messagePattern":"crypto/sha256: invalid hash state identifier","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/boring/sha.go","lineNumber":335,"sourceCode":"\td := (*sha256Ctx)(unsafe.Pointer(&h.ctx))\n\tb = append(b, magic256...)\n\tb = byteorder.BEAppendUint32(b, d.h[0])\n\tb = byteorder.BEAppendUint32(b, d.h[1])\n\tb = byteorder.BEAppendUint32(b, d.h[2])\n\tb = byteorder.BEAppendUint32(b, d.h[3])\n\tb = byteorder.BEAppendUint32(b, d.h[4])\n\tb = byteorder.BEAppendUint32(b, d.h[5])\n\tb = byteorder.BEAppendUint32(b, d.h[6])\n\tb = byteorder.BEAppendUint32(b, d.h[7])\n\tb = append(b, d.x[:d.nx]...)\n\tb = append(b, make([]byte, len(d.x)-int(d.nx))...)\n\tb = byteorder.BEAppendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)\n\treturn b, nil\n}\n\nfunc (h *sha224Hash) UnmarshalBinary(b []byte) error {\n\tif len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 {\n\t\treturn errors.New(\"crypto/sha256: invalid hash state identifier\")\n\t}\n\tif len(b) != marshaledSize256 {\n\t\treturn errors.New(\"crypto/sha256: invalid hash state size\")\n\t}\n\td := (*sha256Ctx)(unsafe.Pointer(&h.ctx))\n\tb = b[len(magic224):]\n\tb, d.h[0] = consumeUint32(b)\n\tb, d.h[1] = consumeUint32(b)\n\tb, d.h[2] = consumeUint32(b)\n\tb, d.h[3] = consumeUint32(b)\n\tb, d.h[4] = consumeUint32(b)\n\tb, d.h[5] = consumeUint32(b)\n\tb, d.h[6] = consumeUint32(b)\n\tb, d.h[7] = consumeUint32(b)\n\tb = b[copy(d.x[:], b):]\n\tb, n := consumeUint64(b)\n\td.nl = uint32(n << 3)\n\td.nh = uint32(n >> 29)","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/boring/sha.go#L317-L353","documentation":"Returned by sha224Hash.UnmarshalBinary in the BoringCrypto SHA-256 backend when the blob does not start with the SHA-224 magic (magic224). SHA-224 and SHA-256 share the same 256-bit block context but use distinct magics so a 224-state cannot be loaded into a 256-state and vice versa.","triggerScenarios":"Calling UnmarshalBinary on a sha256.New224() hash with a blob whose prefix is not magic224 (e.g. a SHA-256 blob, an empty slice, or a SHA-1 blob).","commonSituations":"Mixing up sha256.New224() and sha256.New() when round-tripping state; persisting state from the non-BoringCrypto build; truncation/corruption of the prefix.","solutions":["Ensure the destination hasher matches the source: sha256.New224() for SHA-224 blobs, sha256.New() for SHA-256 blobs.","Re-hash instead of persisting internal state across builds.","Check the magic prefix before calling UnmarshalBinary."],"exampleFix":"// before\nh := sha256.New() // wrong: source was 224\nh.(encoding.BinaryUnmarshalser).UnmarshalBinary(state224)\n// after\nh := sha256.New224()\nh.(encoding.BinaryUnmarshalser).UnmarshalBinary(state224)","handlingStrategy":"validation","validationCode":"// magic224 is package-private; approximate by checking the SHA-256 family magic\n// and use sha256.New224() only for SHA-224-derived blobs.\nfunc looksLikeSHA224State(s []byte) bool {\n    // first byte differs from sha256 magic; verify against your own snapshot\n    return len(s) > 0 && s[0] == 's' // tighten to actual prefix in your build\n}","typeGuard":"// n/a","tryCatchPattern":"if err := h224.(encoding.BinaryUnmarshalser).UnmarshalBinary(state); err != nil {\n    // mismatched family; route to the correct hasher\n}","preventionTips":["Keep SHA-224 and SHA-256 blobs tagged with their algorithm externally.","Do not share UnmarshalBinary targets between 224 and 256.","Re-hash when crossing builds."],"tags":["crypto","sha256","sha224","boringcrypto","serialization","hash"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}