golang/go · error
crypto/sha512: invalid hash state size
Error message
crypto/sha512: invalid hash state size
What it means
Returned by sha512 Digest.UnmarshalBinary when the magic prefix is valid (variant matched) but the total byte length is not marshaledSize. The sha512 layout is fixed-length (magic + 8 x uint64 state + 128-byte block buffer + uint64 length counter); truncation or extra bytes fail this check.
Source
Thrown at src/crypto/internal/fips140/sha512/sha512.go:177
b = append(b, make([]byte, len(d.x)-d.nx)...)
b = byteorder.BEAppendUint64(b, d.len)
return b, nil
}
func (d *Digest) UnmarshalBinary(b []byte) error {
if len(b) < len(magic512) {
return errors.New("crypto/sha512: invalid hash state identifier")
}
switch {
case d.size == size384 && string(b[:len(magic384)]) == magic384:
case d.size == size224 && string(b[:len(magic512_224)]) == magic512_224:
case d.size == size256 && string(b[:len(magic512_256)]) == magic512_256:
case d.size == size512 && string(b[:len(magic512)]) == magic512:
default:
return errors.New("crypto/sha512: invalid hash state identifier")
}
if len(b) != marshaledSize {
return errors.New("crypto/sha512: invalid hash state size")
}
b = b[len(magic512):]
b, d.h[0] = consumeUint64(b)
b, d.h[1] = consumeUint64(b)
b, d.h[2] = consumeUint64(b)
b, d.h[3] = consumeUint64(b)
b, d.h[4] = consumeUint64(b)
b, d.h[5] = consumeUint64(b)
b, d.h[6] = consumeUint64(b)
b, d.h[7] = consumeUint64(b)
b = b[copy(d.x[:], b):]
b, d.len = consumeUint64(b)
d.nx = int(d.len % chunk)
return nil
}
func consumeUint64(b []byte) ([]byte, uint64) {
return b[8:], byteorder.BEUint64(b)View on GitHub (pinned to b6b368adc5)
Solutions
- Store and retrieve the full marshaledSize bytes unchanged; verify byte-for-byte length.
- If data transits a length-prefixed protocol, check the length prefix matches marshaledSize before forwarding.
- Re-hash from the original input if the state is unrecoverable.
- Pin producer and consumer Go major versions when persisting hash state long-term.
Example fix
// before d.UnmarshalBinary(b[:len(b)-1]) // missing last byte -> error // after d.UnmarshalBinary(b) // exact marshaledSize
Defensive patterns
Strategy: validation
Validate before calling
if len(b) != marshaledSize {
return fmt.Errorf("sha512 state size mismatch: got %d want %d", len(b), marshaledSize)
} Prevention
- Verify byte-for-byte length of persisted state on read and write.
- Check length prefixes in transit protocols against marshaledSize.
- Pin producer and consumer Go major versions for long-lived persisted state.
When it happens
Trigger: Passing bytes whose variant magic is correct but whose length differs from the fixed marshaledSize: a buffer truncated by storage, an extra trailing byte appended by a buggy serializer, or bytes from a build with a different marshaled layout.
Common situations: Database BLOB column sized too small and silently truncating; transport framing that drops or duplicates bytes; copy/paste of a hex string that lost or added characters; version skew between producer and consumer Go builds.
Related errors
- crypto/sha512: invalid hash state identifier
- crypto/sha512: invalid hash state identifier
- crypto/sha256: invalid hash state identifier
- crypto/sha256: invalid hash state size
- sha3: invalid hash state
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/9b4c51ae55c1d357.
Report an issue: GitHub.