golang/go · error
crypto/sha512: invalid hash state identifier
Error message
crypto/sha512: invalid hash state identifier
What it means
Returned by sha512 Digest.UnmarshalBinary when len(b) < len(magic512): the input is too short to even contain the magic prefix that identifies the SHA-512 family variant. This is the initial length gate before the variant-specific magic switch runs.
Source
Thrown at src/crypto/internal/fips140/sha512/sha512.go:166
panic("unknown size")
}
b = byteorder.BEAppendUint64(b, d.h[0])
b = byteorder.BEAppendUint64(b, d.h[1])
b = byteorder.BEAppendUint64(b, d.h[2])
b = byteorder.BEAppendUint64(b, d.h[3])
b = byteorder.BEAppendUint64(b, d.h[4])
b = byteorder.BEAppendUint64(b, d.h[5])
b = byteorder.BEAppendUint64(b, d.h[6])
b = byteorder.BEAppendUint64(b, d.h[7])
b = append(b, d.x[:d.nx]...)
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)View on GitHub (pinned to b6b368adc5)
Solutions
- Check len(b) >= len(magic512) (the longest magic in the family) before calling, and discard anything shorter.
- Distinguish 'marshaled state' from 'final digest output' — UnmarshalBinary expects the former, not the latter.
- Verify the read/persistence layer returned the full expected byte count before invoking UnmarshalBinary.
Example fix
// before
d.UnmarshalBinary(nilOrShort) // < magic prefix -> error
// after
if len(b) < marshaledSize { return errors.New("state too short") }
d.UnmarshalBinary(b) Defensive patterns
Strategy: validation
Validate before calling
if len(b) < len(magic512) {
return fmt.Errorf("sha512 state too short: got %d want >= %d", len(b), len(magic512))
} Prevention
- Distinguish 'marshaled state' from 'final digest output'; UnmarshalBinary wants the former.
- Verify the read returned at least the magic prefix length before calling.
- Treat empty/short buffers as corrupt rather than passing them in.
When it happens
Trigger: Calling UnmarshalBinary with an empty slice, a very short slice, or any buffer shorter than the magic prefix length. The switch on d.size (384/224/256/512) is never reached because the input cannot physically hold a magic.
Common situations: Empty/nil buffer returned from a failed read; a framing bug that delivered only the length prefix; persisted state column truncated to near-zero length; calling UnmarshalBinary on bytes that were never actually marshaled (e.g. raw digest output rather than marshaled state).
Related errors
- crypto/sha512: invalid hash state size
- 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/94de6f00a63b1bfa.
Report an issue: GitHub.