golang/go · error
crypto/sha1: invalid hash state identifier
Error message
crypto/sha1: invalid hash state identifier
What it means
Thrown by sha1.digest.UnmarshalBinary when the input does not begin with the sha1 magic identifier. UnmarshalBinary reverses MarshalBinary to restore a hash state; the magic prefix distinguishes a SHA-1 blob from other hash encodings. A missing or wrong prefix means the bytes are not a valid SHA-1 state.
Source
Thrown at src/crypto/sha1/sha1.go:71
return d.AppendBinary(make([]byte, 0, marshaledSize))
}
func (d *digest) AppendBinary(b []byte) ([]byte, error) {
b = append(b, magic...)
b = byteorder.BEAppendUint32(b, d.h[0])
b = byteorder.BEAppendUint32(b, d.h[1])
b = byteorder.BEAppendUint32(b, d.h[2])
b = byteorder.BEAppendUint32(b, d.h[3])
b = byteorder.BEAppendUint32(b, d.h[4])
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(magic) || string(b[:len(magic)]) != magic {
return errors.New("crypto/sha1: invalid hash state identifier")
}
if len(b) != marshaledSize {
return errors.New("crypto/sha1: invalid hash state size")
}
b = b[len(magic):]
b, d.h[0] = consumeUint32(b)
b, d.h[1] = consumeUint32(b)
b, d.h[2] = consumeUint32(b)
b, d.h[3] = consumeUint32(b)
b, d.h[4] = consumeUint32(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
- Ensure the bytes passed to UnmarshalBinary came from a SHA-1 MarshalBinary call.
- Check len(b) >= len(magic) and the magic prefix before calling, returning your own error.
- Use a single hash algorithm end-to-end so states are type-matched.
- If the source is untrusted, treat UnmarshalBinary failure as expected and discard the input.
Example fix
// before
var d sha1.digest
d.UnmarshalBinary(sha256state) // wrong algorithm's blob
// after
if !bytes.HasPrefix(b, []byte("sha\x01")) { // sha1 magic
return errors.New("not a sha1 state")
}
err := d.UnmarshalBinary(b) Defensive patterns
Strategy: validation
Validate before calling
// sha1 magic is "sha\x01" (3 bytes). Verify prefix before UnmarshalBinary.
var sha1Magic = []byte{'s', 'h', 'a', 0x01} // confirm exact bytes from source
func safeUnmarshal(d *sha1.Digest, b []byte) error {
if len(b) < len(sha1Magic) || !bytes.Equal(b[:len(sha1Magic)], sha1Magic) {
return errors.New("not a sha1 marshaled state")
}
return d.UnmarshalBinary(b)
} Prevention
- Marshal and unmarshal with the same hash package; do not mix algorithm blobs.
- Version-stamp persisted hash states so a mismatch is detectable up front.
- Treat UnmarshalBinary as a parser of untrusted input and handle its error.
- Keep gob/json streams that carry hash states on a single hash algorithm.
When it happens
Trigger: Calling UnmarshalBinary (directly, or via encoding/gob, encoding/json with MarshalBinary, or hash.Hash reset/restore) on []byte that is not a SHA-1-marshaled state. Common when the wrong hash's binary blob is fed to a SHA-1 digest.
Common situations: Interchanging marshaled states between SHA-256 and SHA-1; corrupted gob stream storing hash state; truncated blob; passing arbitrary user data to UnmarshalBinary.
Related errors
- crypto/sha1: invalid hash state size
- crypto/sha1: invalid hash state identifier
- crypto/sha1: invalid hash state size
- crypto/sha1: use of SHA-1 is not allowed in FIPS 140-only mo
- globalThis.crypto is not available, polyfill required (crypt
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/5ae7a7c3e92b722b.
Report an issue: GitHub.