crowdsecurity/crowdsec · error
ErrCookieTooLarge
ErrCookieTooLarge
Error message
%w: plaintext=%d > %d
What it means
Before marshaling, sealCookieV0 pre-computes the plaintext size (fixed 11-byte header + reason + protobuf envelope) and rejects anything exceeding the space available within maxCookieLen after base64 expansion, GCM nonce (12 bytes) and tag (16 bytes). The sentinel error is ErrCookieTooLarge. This guards against the 4 KB browser cookie limit and bounds attacker-influenced envelope allocation.
Source
Thrown at pkg/appsec/challenge/crypto.go:135
key, err := deriveKey(masterCookieKey)
if err != nil {
return "", err
}
block, err := aes.NewCipher(key)
if err != nil {
return "", fmt.Errorf("failed to create cipher: %w", err)
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return "", fmt.Errorf("failed to create GCM: %w", err)
}
// Reject an over-limit envelope before marshaling it.
maxPlaintext := maxCookieLen/4*3 - 1 - gcm.NonceSize() - gcm.Overhead()
if plaintextLen := cookiePlaintextFixedHeaderLen + len(reason) + proto.Size(envelope); plaintextLen > maxPlaintext {
return "", fmt.Errorf("%w: plaintext=%d > %d", ErrCookieTooLarge, plaintextLen, maxPlaintext)
}
envelopeBytes, err := proto.Marshal(envelope)
if err != nil {
return "", fmt.Errorf("failed to marshal challenge cookie proto: %w", err)
}
nonce := make([]byte, gcm.NonceSize())
if _, err := rand.Read(nonce); err != nil {
return "", fmt.Errorf("failed to generate nonce: %w", err)
}
// Build the plaintext: not_after_be8 || flags || reason_len_be || reason || envelope
plaintext := make([]byte, 0, cookiePlaintextFixedHeaderLen+len(reason)+len(envelopeBytes))
var notAfterBytes [8]byte
binary.BigEndian.PutUint64(notAfterBytes[:], uint64(notAfter))
plaintext = append(plaintext, notAfterBytes[:]...)View on GitHub (pinned to 909b515798)
Solutions
- Raise the max_cookie_size challenge config value (default 4096) if the client tolerates larger cookies.
- Reduce the reason length (allowlist cookies) or slim the fingerprint envelope payload.
- Match errors.Is(err, challenge.ErrCookieTooLarge) to surface a clear 'cookie too large' message instead of a generic seal failure.
Example fix
# before max_cookie_size: 2048 # after max_cookie_size: 4096
Defensive patterns
Strategy: validation
Validate before calling
const maxCookieSize = 4096 // must be >= default; keep headroom for reason + envelope
if cfg.MaxCookieSize != nil && *cfg.MaxCookieSize < 4096 {
log.Warn("max_cookie_size below default may reject valid fingerprint envelopes")
} Try / catch
if err := errors.Is(err, challenge.ErrCookieTooLarge); err != nil {
// raise max_cookie_size or trim reason/envelope, then retry once
} Prevention
- Leave max_cookie_size at the 4096 default unless the client cannot carry 4 KB cookies.
- Keep the fingerprint envelope small; do not stuff extra data into it.
- Budget: reason (max 256) + envelope must fit in ~3040 plaintext bytes.
When it happens
Trigger: Calling sealCookieV0 with an envelope whose protobuf size plus reason length exceeds maxPlaintext = maxCookieLen/4*3 - 1 - 12 - 16; with default maxCookieLen 4096 that is ~3040 bytes. Reached via SealAllowlistCookie (large reason) or ValidateChallengeResponse (large fingerprint proto), or when max_cookie_size is configured lower than the payload.
Common situations: Deployments lowering max_cookie_size in appsec config below what the fingerprint envelope requires; unusually large fingerprint data (many attributes) stored in the envelope; an allowlist reason near the 256-byte cap combined with a big proto.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- cookie exceeds maximum size
- allowlist reason exceeds maximum length
- invalid challenge cookie: %w
- ErrAllowlistReasonSize
- invalid schema name
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/e38a9a2c517a1c34.
Report an issue: GitHub.