{"record":{"id":"8daa5d59f9348313","repo":"golang/go","slug":"crypto-sha256-invalid-hash-state-size","errorCode":null,"errorMessage":"crypto/sha256: invalid hash state size","messagePattern":"crypto/sha256: invalid hash state size","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/boring/sha.go","lineNumber":338,"sourceCode":"\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)\n\td.nx = uint32(n) % 64\n\treturn nil\n}","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/boring/sha.go#L320-L356","documentation":"Returned by sha224Hash.UnmarshalBinary when the magic matches SHA-224 but the total length is not marshaledSize256. The SHA-224 and SHA-256 contexts share the same marshalled size constant, so this length check is shared between both UnmarshalBinary methods.","triggerScenarios":"Calling UnmarshalBinary on a sha256.New224() hash with a blob of correct SHA-224 magic but wrong total length.","commonSituations":"Truncated/padded persisted state; state produced by a Go version with a different marshalled layout; corruption in transport/storage.","solutions":["Validate length equals marshaledSize256 before unmarshalling.","Regenerate the persisted blob from the current Go build.","Re-hash the original data instead of restoring state."],"exampleFix":"// before\nh := sha256.New224()\nh.(encoding.BinaryUnmarshalser).UnmarshalBinary(truncatedState)\n// after\nif !validSHA256FamilyState(state) { return errors.New(\"bad state\") }\nh.(encoding.BinaryUnmarshalser).UnmarshalBinary(state)","handlingStrategy":"validation","validationCode":"// marshaledSize256 for the BoringCrypto build\nconst sha256MarshaledSize = 4 + 8*4 + 64 + 8 // = 108\nfunc validSHA256FamilyState(s []byte) bool {\n    return len(s) == sha256MarshaledSize && s[0] == 's'\n}","typeGuard":"// n/a","tryCatchPattern":"if err := h224.(encoding.BinaryUnmarshalser).UnmarshalBinary(state); err != nil {\n    return err\n}","preventionTips":["Validate length before unmarshalling.","Version your persisted state format.","Regenerate blobs on Go upgrades."],"tags":["crypto","sha256","sha224","boringcrypto","serialization","validation"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}