{"record":{"id":"6a6f35746a0f1115","repo":"thephpleague/oauth2-server","slug":"server-error-unsupported-code-challenge-method-s","errorCode":"server_error","errorMessage":"Unsupported code challenge method `%s`","messagePattern":"Unsupported code challenge method `(.+?)`","errorType":"http","errorClass":"OAuthServerException","httpStatus":500,"severity":"error","filePath":"src/Grant/AuthCodeGrant.php","lineNumber":186,"sourceCode":"            throw OAuthServerException::invalidRequest(\n                'code_verifier',\n                'Code Verifier must follow the specifications of RFC-7636.'\n            );\n        }\n\n        if (property_exists($authCodePayload, 'code_challenge_method')) {\n            if (isset($this->codeChallengeVerifiers[$authCodePayload->code_challenge_method])) {\n                $codeChallengeVerifier = $this->codeChallengeVerifiers[$authCodePayload->code_challenge_method];\n\n                if (\n                    !property_exists($authCodePayload, 'code_challenge') ||\n                    !isset($authCodePayload->code_challenge) ||\n                    $codeChallengeVerifier->verifyCodeChallenge($codeVerifier, $authCodePayload->code_challenge) === false\n                ) {\n                    throw OAuthServerException::invalidGrant('Failed to verify `code_verifier`.');\n                }\n            } else {\n                throw OAuthServerException::serverError(\n                    sprintf(\n                        'Unsupported code challenge method `%s`',\n                        $authCodePayload->code_challenge_method\n                    )\n                );\n            }\n        }\n    }\n\n    /**\n     * Validate the authorization code.\n     */\n    private function validateAuthorizationCode(\n        stdClass $authCodePayload,\n        ClientEntityInterface $client,\n        ServerRequestInterface $request\n    ): void {\n        if (!property_exists($authCodePayload, 'auth_code_id')) {","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/thephpleague/oauth2-server/blob/9d2f6fc0a0b5aa1bb02506971d3a4ecff2c6526c/src/Grant/AuthCodeGrant.php#L168-L204","documentation":"This server_error is thrown by AuthCodeGrant::validateCodeChallenge when the stored authorization-code payload contains a `code_challenge_method` that the grant does not support (only `plain` and `S256` are allowed). It is a server-side configuration/issue-time problem, not a client verifier mismatch, and intentionally returns HTTP 500-class code `server_error` per RFC 6749 semantics.","triggerScenarios":"Exchanging an authorization code whose payload's code_challenge_method is anything other than 'plain' or 'S256' — typically because the authorization request specified code_challenge_method=unsupported-value (e.g. 'S256 ' with whitespace, lowercase variants, or a custom method) and it was stored verbatim, or the payload was hand-crafted/tampered with.","commonSituations":"A proxy or client SDK sent a non-standard code_challenge_method value that the server persisted; custom storage adapters that lower/uppercase or mutate the method string; forged or stale cached payloads; a server that enabled proof exchange without restricting the method on authorize.","solutions":["Re-issue the authorization code requesting code_challenge_method=S256 (or plain) exactly, with no whitespace or case variants.","Validate/normalize code_challenge_method at the authorize endpoint before persisting the payload (reject unknown values there).","Check custom AuthCodePayload serialization/deserialization and any storage middleware that could alter the method string.","Upgrade league/oauth2-server to a version whose validateAuthorizationCode/authorize path restricts challenge methods to S256/plain."],"exampleFix":"// before: authorize endpoint accepts any method and stores it\n$payload->code_challenge_method = $request->getQueryParams()['code_challenge_method'];\n// after\n$method = $request->getQueryParams()['code_challenge_method'] ?? null;\nif (!in_array($method, ['plain', 'S256'], true)) {\n    throw OAuthServerException::invalidRequest('code_challenge_method');\n}\n$payload->code_challenge_method = $method;","handlingStrategy":"validation","validationCode":"// at the authorize endpoint, before storing the payload\n$method = $_GET['code_challenge_method'] ?? null;\nif (isset($_GET['code_challenge']) && !in_array($method, ['plain', 'S256'], true)) {\n    throw OAuthServerException::invalidRequest('code_challenge_method');\n}","typeGuard":null,"tryCatchPattern":"try {\n    $token = $server->respondToAccessTokenRequest($request, $response);\n} catch (\\League\\OAuth2\\Server\\Exception\\OAuthServerException $e) {\n    if ($e->getCode() === 'server_error' && str_contains($e->getMessage(), 'code challenge method')) {\n        // log the offending stored method; re-issue code with S256\n    }\n    throw $e;\n}","preventionTips":["Whitelist code_challenge_method to S256 (preferred) or plain at the authorize endpoint.","Never persist the raw query parameter without validation.","Check custom payload serializers/storage layers do not mutate the method string.","Prefer S256 everywhere; 'plain' is deprecated by RFC 7636 best practice."],"tags":["oauth2","pkce","server-error","php"],"backgroundTag":"unsupported-enum-value","analyzedSha":"9d2f6fc0a0b5aa1bb02506971d3a4ecff2c6526c","analyzedAt":"2026-09-15T22:33:30.452Z","contentChangedAt":"2026-09-15T22:33:30.452Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}