{"record":{"id":"a876ce8b5a67db64","repo":"crowdsecurity/crowdsec","slug":"errchallengeticket","errorCode":"ErrChallengeTicket","errorMessage":"invalid ticket in challenge response","messagePattern":"invalid ticket in challenge response","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/appsec/challenge/challenge.go","lineNumber":60,"sourceCode":"\t\"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1\"\n\t\"golang.org/x/sync/singleflight\"\n\t\"golang.org/x/sys/cpu\"\n)\n\n// Internal URL paths the challenge runtime intercepts. Bouncers MUST forward\n// these to the WAF unmodified; they are served by the appsec dispatcher\n// (pkg/appsec/appsec.go) rather than by the protected origin.\nconst (\n\tChallengeJSPath        = \"/crowdsec-internal/challenge/challenge.js\"\n\tChallengeSubmitPath    = \"/crowdsec-internal/challenge/submit\"\n\tChallengePowWorkerPath = \"/crowdsec-internal/challenge/pow-worker.js\"\n\tChallengeFPScannerPath = \"/crowdsec-internal/challenge/fpscanner.js\"\n)\n\n// Sentinel errors (reasons) returned by ValidateChallengeResponse.\nvar (\n\tErrChallengeFields     = errors.New(\"missing required fields in challenge response\")\n\tErrChallengeTicket     = errors.New(\"invalid ticket in challenge response\")\n\tErrChallengeDifficulty = errors.New(\"challenge difficulty is impossible\")\n\tErrChallengePoW        = errors.New(\"invalid proof-of-work in challenge response\")\n\tErrChallengeHMAC       = errors.New(\"invalid HMAC in challenge response\")\n\tErrChallengePayload    = errors.New(\"invalid challenge response payload\")\n)\n\n// ChallengeCookieName is the name of the sealed cookie carrying the\n// successfully-validated fingerprint between requests.\nconst ChallengeCookieName = \"__crowdsec_challenge\"\n\n// cryptoObfuscationPoolDefaultSize is how many obfuscations of the per-epoch\n// key module to keep per live epoch. Each variant embeds the same key\n// differently (per-visitor byte variance); default 1 keeps prior behavior.\nconst cryptoObfuscationPoolDefaultSize = 1\n\n// defaultCookieTTL is the default challenge-cookie validity. Decoupled from the\n// keyring window (enforced by not_after in the envelope), so cookies can\n// outlive the per-epoch signing window without widening forgery exposure.","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/challenge/challenge.go#L42-L78","documentation":"ErrChallengeTicket is a sentinel reason returned by ValidateChallengeResponse when the ticket embedded in the client's challenge answer is invalid — absent, expired, signed incorrectly, or not matching a challenge the server issued. The AppSec layer maps it to the reason code \"ticket\" when reporting the failed challenge.","triggerScenarios":"A client submits a challenge response whose ticket fails server-side validation, e.g. the ticket was issued before a crowdsec restart, the server-side signing state changed, or the ticket was tampered with.","commonSituations":"Load-balanced setups where challenge state is not shared between crowdsec instances; a long-running challenge solved after ticket expiry; clients replaying an old challenge response; clock skew affecting ticket validity.","solutions":["Have the client request a fresh challenge page and re-solve it, so a new valid ticket is minted","If behind a load balancer, ensure all crowdsec AppSec instances share ticket/secret state or route the same client consistently","Check server clock and ticket TTL configuration if tickets expire too quickly","Verify no intermediary rewrites or truncates the ticket field in the submitted response"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if errors.Is(err, challenge.ErrChallengeTicket) {\n    // return reason \"ticket\" and re-issue a new challenge page to the client\n    w.Logger.Debugf(\"challenge ticket invalid: %v\", err)\n}","preventionTips":["Share challenge signing secrets/state across load-balanced crowdsec nodes","Set ticket TTLs long enough for users to solve the challenge","Serve a fresh challenge automatically on ticket errors"],"tags":["appsec","challenge","ticket"],"backgroundTag":"invalid-token","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}