crowdsecurity/crowdsec · error

unable to seal allowlist cookie: %w

Error message

unable to seal allowlist cookie: %w

What it means

When a request is allowlisted at the challenge layer, the engine seals an allowlist cookie via ChallengeRuntime.SealAllowlistCookie so the client can present proof on later requests. If sealing fails (keyring/crypto error, bad request context), this error wraps it and the allowlist response cannot be produced.

Source

Thrown at pkg/appsec/appsec.go:1714

	return nil
}

// mintAllowlistCookie seals a v0 allowlist cookie, stamps a synthetic
// Allowlisted fingerprint, and flips state.ChallengeBypassed so any later
// SendChallenge in the same request is a no-op. The caller decides how the
// cookie reaches the visitor (redirect vs. inline envelope).
//
// It DELIBERATELY overwrites any prior state.Fingerprint from a real
// submission: an operator allowlist wins. ttlOverride (non-nil) overrides the
// runtime cookie_ttl. Returns ErrAllowlistReasonSize if reason is too long.
func (w *AppsecRuntimeConfig) mintAllowlistCookie(state *AppsecRequestState, request *ParsedRequest, reason string, ttlOverride *time.Duration) (*cookie.AppsecCookie, error) {
	if w.ChallengeRuntime == nil {
		return nil, errors.New("challenge runtime not initialized")
	}

	ck, err := w.ChallengeRuntime.SealAllowlistCookie(request.HTTPRequest, reason, ttlOverride)
	if err != nil {
		return nil, fmt.Errorf("unable to seal allowlist cookie: %w", err)
	}

	state.Fingerprint = &challenge.FingerprintData{
		Allowlisted:     true,
		AllowlistReason: reason,
	}
	state.ChallengeBypassed = true

	// One increment here covers both GrantChallengeCookie (307 redirect from
	// pre_eval/post_eval) and GrantAllowlistCookieInline (inline on the
	// challenge-submit response). Both delegate to this function.
	metrics.AppsecChallengeAccepted.With(prometheus.Labels{
		"source":        request.RemoteAddrNormalized,
		"appsec_engine": request.AppsecEngine,
		"kind":          "granted",
		"reason":        reason, // operator-supplied string passed to GrantChallengeCookie
	}).Inc()

View on GitHub (pinned to 909b515798)

Solutions

  1. Check the wrapped error for key/seal failures and verify the challenge keys in the data directory are present and readable
  2. Fix filesystem permissions on the crowdsec data dir
  3. Restart crowdsec so the challenge runtime reloads its keys
  4. Validate any ttl override configuration passed to the allowlist path
Defensive patterns

Strategy: try-catch

Validate before calling

if w.ChallengeRuntime == nil {
    return errors.New("challenge runtime not initialized")
}

Try / catch

ck, err := w.ChallengeRuntime.SealAllowlistCookie(req, reason, ttl)
if err != nil {
    log.Errorf("allowlist cookie seal failed, denying without cookie: %v", err)
    return nil, err
}

Prevention

When it happens

Trigger: SealAllowlistCookie returning an error: missing or corrupted sealing key, cookie value serialization failure, or challenge runtime misconfiguration at startup.

Common situations: Regenerated/rotated challenge keys leaving the runtime without a valid key; data dir permission issues preventing key load; cookie TTL/ttlOverride values that fail validation.

Related errors


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