golang/go · error
hkdf: requested key length too large
Error message
hkdf: requested key length too large
What it means
Thrown by hkdf.Expand (hkdf.go:50) when the requested keyLength exceeds fh().Size() * 255. HKDF-Expand produces at most 255 blocks (RFC 5869 §2.3); requesting more is a protocol-violating input. The limit depends on the chosen hash's output size.
Source
Thrown at src/crypto/hkdf/hkdf.go:50
return hkdf.Extract(fh, secret, salt), nil
}
// Expand derives a key from the given hash, key, and optional context info,
// returning a []byte of length keyLength that can be used as cryptographic key.
// The extraction step is skipped.
//
// The key should have been generated by [Extract], or be a uniformly
// random or pseudorandom cryptographically strong key. See RFC 5869, Section
// 3.3. Most common scenarios will want to use [Key] instead.
func Expand[H hash.Hash](h func() H, pseudorandomKey []byte, info string, keyLength int) ([]byte, error) {
fh := fips140hash.UnwrapNew(h)
if err := checkFIPS140Only(fh, pseudorandomKey); err != nil {
return nil, err
}
limit := fh().Size() * 255
if keyLength > limit {
return nil, errors.New("hkdf: requested key length too large")
}
return hkdf.Expand(fh, pseudorandomKey, info, keyLength), nil
}
// Key derives a key from the given hash, secret, salt and context info,
// returning a []byte of length keyLength that can be used as cryptographic key.
// Salt and info can be nil.
func Key[Hash hash.Hash](h func() Hash, secret, salt []byte, info string, keyLength int) ([]byte, error) {
fh := fips140hash.UnwrapNew(h)
if err := checkFIPS140Only(fh, secret); err != nil {
return nil, err
}
limit := fh().Size() * 255
if keyLength > limit {
return nil, errors.New("hkdf: requested key length too large")
}View on GitHub (pinned to b6b368adc5)
Solutions
- Cap keyLength to <= 255 * hashSize before calling Expand; for SHA-256 that is 8160 bytes.
- Fix unit confusion — HKDF takes keyLength in bytes, not bits.
- If you need more keying material than the limit, derive intermediate keys and chain HKDF rounds.
Example fix
// before
key, err := hkdf.Expand(sha256.New, prk, "", 1<<20) // > 8160 -> error 255
// after
const limit = sha256.Size * 255 // 8160
want := 64
if want > limit { return fmt.Errorf("key too long") }
key, err := hkdf.Expand(sha256.New, prk, "", want) Defensive patterns
Strategy: validation
Validate before calling
limit := sha256.Size * 255 // example for SHA-256
if keyLength > limit || keyLength <= 0 {
return fmt.Errorf("keyLength must be in [1, %d]", limit)
} Type guard
func hkdfExpandLenOK(hashSize, keyLength int) bool {
return keyLength > 0 && keyLength <= hashSize*255
} Prevention
- Treat keyLength as bytes, not bits.
- Cap derived key length at 255 * hashSize; chain HKDF rounds for more material.
- Bound keyLength when it comes from untrusted input.
When it happens
Trigger: Calling hkdf.Expand(sha256.New, prk, info, keyLength) with keyLength > 255*32 (8160 bytes for SHA-256) — or any hash where keyLength > 255*Size. Common when keyLength is computed from a config or derived value without an upper-bound check.
Common situations: Deriving very long output for a custom KDF chain; keyLength sourced from a length field in an untrusted message; off-by units (bits vs bytes) producing a huge number.
Related errors
- crypto/dsa: invalid public key
- crypto/dsa: invalid ParameterSizes
- crypto/dsa: parameters not set up before generating key
- crypto/ecdh: private key and public key curves do not match
- crypto/ecdh: invalid private key
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/b8de290003485baf.
Report an issue: GitHub.