crowdsecurity/crowdsec · error

failed to seal allowlist cookie: %w

Error message

failed to seal allowlist cookie: %w

What it means

SealAllowlistCookie mints an AES-GCM-sealed allowlist-bypass challenge cookie, encrypting the envelope under the master cookie key. This wrapper error means the underlying sealCookieV0 call failed, so no allowlist cookie could be produced and GrantChallengeCookie cannot grant the bypass. It always wraps one of the crypto-layer errors: reason too long, proto marshal failure, size-limit breach, or entropy failure.

Source

Thrown at pkg/appsec/challenge/challenge.go:754

// SealAllowlistCookie mints an allowlist-bypass cookie (no fingerprint, with
// the operator reason) so GrantChallengeCookie can let trusted bots skip the
// challenge UI while still hitting on_challenge rules via fingerprint.Allowlisted.
// not_after honors c.cookieTTL unless ttlOverride (>0) is given; reason is
// bounded by MaxAllowlistReasonLen (crypto.go).
func (c *ChallengeRuntime) SealAllowlistCookie(request *http.Request, reason string, ttlOverride *time.Duration) (*cookie.AppsecCookie, error) {
	if c == nil {
		return nil, errors.New("challenge runtime not initialized")
	}

	ttl := c.cookieTTL
	if ttlOverride != nil && *ttlOverride > 0 {
		ttl = *ttlOverride
	}

	notAfter := time.Now().Add(ttl).Unix()
	cookieValue, err := sealCookieV0(&pb.ChallengeCookie{}, c.keys.MasterCookieKey(), notAfter, cookieFlagAllowlisted, reason, []byte(request.UserAgent()), c.maxCookieLen)
	if err != nil {
		return nil, fmt.Errorf("failed to seal allowlist cookie: %w", err)
	}

	ck := cookie.NewAppsecCookie(ChallengeCookieName).HttpOnly().Path("/").SameSite(cookie.SameSiteLax).ExpiresIn(ttl).Value(cookieValue)
	if request.URL.Scheme == "https" {
		ck = ck.Secure()
	}

	return ck, nil
}

// CookieData bundles the decoded fingerprint with cookie-envelope metadata for
// re-challenge decisions. Allowlisted/AllowlistReason mark cookies minted by
// SealAllowlistCookie; they are zero for real-submission cookies.
type CookieData struct {
	Fingerprint     FingerprintData
	PowDifficulty   int
	Allowlisted     bool
	AllowlistReason string

View on GitHub (pinned to 909b515798)

Solutions

  1. Shorten the reason string passed to SealAllowlistCookie/GrantChallengeCookie to at most 256 bytes.
  2. If ErrCookieTooLarge is wrapped, raise the max_cookie_size challenge config value or reduce the cookie payload.
  3. Check the wrapped error (%w chain) to identify the exact crypto-layer cause; entropy failures (rand.Read) indicate a broken system CSPRNG.
  4. Verify the runtime was initialized (nil runtime returns a different error, but a half-initialized keyring is worth ruling out).

Example fix

// before
ck, err := rt.SealAllowlistCookie(req, "allowlisted for support ticket #4821 - trusted corporate proxy scanning partner integration from the security operations center", nil)
// after
reason := "support ticket #4821 - trusted proxy"
if len(reason) > challenge.MaxAllowlistReasonLen {
    reason = reason[:challenge.MaxAllowlistReasonLen]
}
ck, err := rt.SealAllowlistCookie(req, reason, nil)
Defensive patterns

Strategy: validation

Validate before calling

if len(reason) > challenge.MaxAllowlistReasonLen {
    return fmt.Errorf("allowlist reason too long: %d > %d", len(reason), challenge.MaxAllowlistReasonLen)
}

Try / catch

if _, err := rt.SealAllowlistCookie(req, reason, nil); err != nil {
    if errors.Is(err, challenge.ErrAllowlistReasonSize) { /* truncate reason and retry */ }
    return err
}

Prevention

When it happens

Trigger: Calling ChallengeRuntime.SealAllowlistCookie (via GrantChallengeCookie) with an operator reason longer than MaxAllowlistReasonLen (256 bytes), or when the resulting plaintext exceeds the configured max cookie size, or an internal crypto/entropy failure.

Common situations: Operators passing a long human-readable allowlist reason (e.g. a URL, ticket ID, or description) through the allowlist API; deployments with a reduced max_cookie_size config value sealing larger envelopes.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/7d50440af11dbfd8. Report an issue: GitHub.