golang/go · error
sha3: invalid hash state function
Error message
sha3: invalid hash state function
What it means
Returned by sha3 Digest.UnmarshalBinary when the rate byte embedded in the marshaled state does not equal the digest instance's configured rate. The rate (block size in bytes) is what distinguishes SHA3-224 (rate 144), SHA3-256 (rate 136), SHA3-384 (rate 104), SHA3-512 (rate 72), and the SHAKE variants. A mismatch means the bytes belong to a different output size of the family even if the magic matched.
Source
Thrown at src/crypto/internal/fips140/sha3/sha3.go:216
if len(b) != marshaledSize {
return errors.New("sha3: invalid hash state")
}
magic := string(b[:len(magicSHA3)])
b = b[len(magicSHA3):]
switch {
case magic == magicSHA3 && d.dsbyte == dsbyteSHA3:
case magic == magicShake && d.dsbyte == dsbyteShake:
case magic == magicCShake && d.dsbyte == dsbyteCShake:
case magic == magicKeccak && d.dsbyte == dsbyteKeccak:
default:
return errors.New("sha3: invalid hash state identifier")
}
rate := int(b[0])
b = b[1:]
if rate != d.rate {
return errors.New("sha3: invalid hash state function")
}
copy(d.a[:], b)
b = b[len(d.a):]
n, state := int(b[0]), spongeDirection(b[1])
if n > d.rate {
return errors.New("sha3: invalid hash state")
}
d.n = n
if state != spongeAbsorbing && state != spongeSqueezing {
return errors.New("sha3: invalid hash state")
}
d.state = state
return nil
}
View on GitHub (pinned to b6b368adc5)
Solutions
- Use the exact same output-size constructor on both ends (e.g. New256 with New256-produced bytes).
- If you changed the digest size, treat old persisted state as invalid and re-hash.
- Store the output size alongside the state and verify it before calling UnmarshalBinary.
Example fix
// before d := sha3.New256() // rate 136 d.(*sha3.Digest).UnmarshalBinary(stateFromSHA3_512) // rate 72 -> error // after d := sha3.New512() d.(*sha3.Digest).UnmarshalBinary(stateFromSHA3_512)
Defensive patterns
Strategy: validation
Validate before calling
wantRate := digestInstance.rate // inspect or expose on your type
if int(b[0]) != wantRate {
return errors.New("marshaled state belongs to a different SHA-3 output size")
} Prevention
- Use the same output-size constructor on both ends (New256 with New256 bytes, etc.).
- When changing digest size, invalidate previously persisted state.
- Store the output size alongside the marshaled state and verify before UnmarshalBinary.
When it happens
Trigger: Calling UnmarshalBinary on a SHA3-256 digest with state produced by a SHA3-512 digest (both use dsbyteSHA3 / magicSHA3, so they pass the magic check but differ in rate); or on a SHAKE128 with SHAKE256 state.
Common situations: Switching the application from SHA3-256 to SHA3-512 (or between SHAKE128 and SHAKE256) without invalidating previously persisted hash state; constructor-vs-producer mismatch on output size.
Related errors
- sha3: invalid hash state
- sha3: invalid hash state identifier
- sha3: invalid hash state
- crypto/sha256: invalid hash state identifier
- crypto/sha256: invalid hash state size
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/744b5e8a8666e825.
Report an issue: GitHub.