golang/go · error

crypto/sha512: invalid hash state identifier

Error message

crypto/sha512: invalid hash state identifier

What it means

Returned by sha384Hash.UnmarshalBinary in the BoringCrypto SHA-512 backend when the blob is shorter than magic512, so the prefix cannot even be read safely. SHA-384 and SHA-512 share the 512-bit block context and the magic512 prefix, but the SHA-384 method additionally requires the prefix to equal magic384.

Source

Thrown at src/crypto/internal/boring/sha.go:518

	d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
	b = append(b, magic512...)
	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)-int(d.nx))...)
	b = byteorder.BEAppendUint64(b, d.nl>>3|d.nh<<61)
	return b, nil
}

func (h *sha384Hash) UnmarshalBinary(b []byte) error {
	if len(b) < len(magic512) {
		return errors.New("crypto/sha512: invalid hash state identifier")
	}
	if string(b[:len(magic384)]) != magic384 {
		return errors.New("crypto/sha512: invalid hash state identifier")
	}
	if len(b) != marshaledSize512 {
		return errors.New("crypto/sha512: invalid hash state size")
	}
	d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
	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):]

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Validate len(state) >= len(magic512) before unmarshalling.
  2. Regenerate the blob from the current Go build.
  3. Re-hash instead of persisting state.

Example fix

// before
h := sha512.New384()
h.(encoding.BinaryUnmarshalser).UnmarshalBinary(shortState)
// after
if len(state) < 6 { return errors.New("state too short") }
h.(encoding.BinaryUnmarshalser).UnmarshalBinary(state)
Defensive patterns

Strategy: validation

Validate before calling

func validSHA512FamilyState(s []byte) bool {
    return len(s) >= 6 // len(magic512)
}

Type guard

// n/a

Try / catch

if err := h384.(encoding.BinaryUnmarshalser).UnmarshalBinary(state); err != nil {
    return err
}

Prevention

When it happens

Trigger: Calling UnmarshalBinary on a sha512.New384() hash with a blob shorter than len(magic512).

Common situations: Empty or near-empty state blob; truncated persisted state; feeding a SHA-256 blob into a SHA-384 hasher.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/8626c6ab83368955. Report an issue: GitHub.