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

  1. Cap keyLength to <= 255 * hashSize before calling Expand; for SHA-256 that is 8160 bytes.
  2. Fix unit confusion — HKDF takes keyLength in bytes, not bits.
  3. 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

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


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