{"record":{"id":"a104b7aa602a9f27","repo":"crowdsecurity/crowdsec","slug":"unable-to-seal-allowlist-cookie-w","errorCode":null,"errorMessage":"unable to seal allowlist cookie: %w","messagePattern":"unable to seal allowlist cookie: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/appsec.go","lineNumber":1714,"sourceCode":"\treturn nil\n}\n\n// mintAllowlistCookie seals a v0 allowlist cookie, stamps a synthetic\n// Allowlisted fingerprint, and flips state.ChallengeBypassed so any later\n// SendChallenge in the same request is a no-op. The caller decides how the\n// cookie reaches the visitor (redirect vs. inline envelope).\n//\n// It DELIBERATELY overwrites any prior state.Fingerprint from a real\n// submission: an operator allowlist wins. ttlOverride (non-nil) overrides the\n// runtime cookie_ttl. Returns ErrAllowlistReasonSize if reason is too long.\nfunc (w *AppsecRuntimeConfig) mintAllowlistCookie(state *AppsecRequestState, request *ParsedRequest, reason string, ttlOverride *time.Duration) (*cookie.AppsecCookie, error) {\n\tif w.ChallengeRuntime == nil {\n\t\treturn nil, errors.New(\"challenge runtime not initialized\")\n\t}\n\n\tck, err := w.ChallengeRuntime.SealAllowlistCookie(request.HTTPRequest, reason, ttlOverride)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to seal allowlist cookie: %w\", err)\n\t}\n\n\tstate.Fingerprint = &challenge.FingerprintData{\n\t\tAllowlisted:     true,\n\t\tAllowlistReason: reason,\n\t}\n\tstate.ChallengeBypassed = true\n\n\t// One increment here covers both GrantChallengeCookie (307 redirect from\n\t// pre_eval/post_eval) and GrantAllowlistCookieInline (inline on the\n\t// challenge-submit response). Both delegate to this function.\n\tmetrics.AppsecChallengeAccepted.With(prometheus.Labels{\n\t\t\"source\":        request.RemoteAddrNormalized,\n\t\t\"appsec_engine\": request.AppsecEngine,\n\t\t\"kind\":          \"granted\",\n\t\t\"reason\":        reason, // operator-supplied string passed to GrantChallengeCookie\n\t}).Inc()\n","sourceCodeStart":1696,"sourceCodeEnd":1732,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/appsec.go#L1696-L1732","documentation":"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.","triggerScenarios":"SealAllowlistCookie returning an error: missing or corrupted sealing key, cookie value serialization failure, or challenge runtime misconfiguration at startup.","commonSituations":"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.","solutions":["Check the wrapped error for key/seal failures and verify the challenge keys in the data directory are present and readable","Fix filesystem permissions on the crowdsec data dir","Restart crowdsec so the challenge runtime reloads its keys","Validate any ttl override configuration passed to the allowlist path"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if w.ChallengeRuntime == nil {\n    return errors.New(\"challenge runtime not initialized\")\n}","typeGuard":null,"tryCatchPattern":"ck, err := w.ChallengeRuntime.SealAllowlistCookie(req, reason, ttl)\nif err != nil {\n    log.Errorf(\"allowlist cookie seal failed, denying without cookie: %v\", err)\n    return nil, err\n}","preventionTips":["Check data-dir key file readability for the crowdsec user after deployments","Rotate keys with a documented procedure and restart the service","Monitor for this error as a sign of key/config corruption"],"tags":["appsec","challenge","cookie"],"backgroundTag":"cookie-sealing-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}