{"record":{"id":"50e86e2376dfcd5c","repo":"phacility/phabricator","slug":"the-authentication-provider-did-not-return-a-clien","errorCode":null,"errorMessage":"The authentication provider did not return a client state parameter in its response, but one was expected. If this problem persists, you may need to clear your cookies.","messagePattern":"The authentication provider did not return a client state parameter in its response, but one was expected\\. If this problem persists, you may need to clear your cookies\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/auth/provider/PhabricatorAuthProvider.php","lineNumber":566,"sourceCode":"    if (!strlen($phcid)) {\n      throw new AphrontMalformedRequestException(\n        pht('Missing Client ID Cookie'),\n        pht(\n          'Your browser did not submit a \"%s\" cookie with client state '.\n          'information in the request. Check that cookies are enabled. '.\n          'If this problem persists, you may need to clear your cookies.',\n          PhabricatorCookies::COOKIE_CLIENTID),\n        true);\n    }\n\n    return PhabricatorHash::weakDigest($phcid);\n  }\n\n  protected function verifyAuthCSRFCode(AphrontRequest $request, $actual) {\n    $expect = $this->getAuthCSRFCode($request);\n\n    if (!strlen($actual)) {\n      throw new Exception(\n        pht(\n          'The authentication provider did not return a client state '.\n          'parameter in its response, but one was expected. If this '.\n          'problem persists, you may need to clear your cookies.'));\n    }\n\n    if (!phutil_hashes_are_identical($actual, $expect)) {\n      throw new Exception(\n        pht(\n          'The authentication provider did not return the correct client '.\n          'state parameter in its response. If this problem persists, you may '.\n          'need to clear your cookies.'));\n    }\n  }\n\n  public function supportsAutoLogin() {\n    return false;\n  }","sourceCodeStart":548,"sourceCodeEnd":584,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/auth/provider/PhabricatorAuthProvider.php#L548-L584","documentation":"Thrown by PhabricatorAuthProvider::verifyAuthCSRFCode() when the identity provider's response contains an empty/absent 'state' (client state) parameter. The verify step first computes the expected digest from the phcid cookie, then requires the provider-supplied state to be a non-empty string; an empty actual value fails here, before any comparison happens. It is an Exception, not a usage exception, because the fault is in the handshake data, not the operator.","triggerScenarios":"The OAuth/OIDC provider redirects back to Phabricator without a state parameter in the query string: the provider is misconfigured and drops state, a custom-built adapter forgot to forward the state through the authorization round-trip, or a hand-crafted/replayed callback URL omits it.","commonSituations":"Custom provider adapter where the callback URI handler loses the state; an upstream IdP policy change that strips unknown parameters; someone bookmarks or manually crafts the callback URL; a reverse proxy rewrites/strips query parameters on the return path.","solutions":["Confirm the authorization request Phabricator sends actually includes state, and that the IdP echoes it back on the exact registered callback URL.","Inspect the provider's redirect URL — if state is missing there, fix the provider/adapter configuration (or the custom adapter's getRedirectURI handling) to round-trip it.","Check reverse proxies / CDNs / rewrite rules between the IdP and Phabricator for query-string stripping, and bypass or fix them for the callback path.","Have the user retry from a fresh login (clearing stale cookies), since the accompanying advice also applies when the phcid-side state expired."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// In a custom adapter, never dispatch a callback with an empty state\nif (!strlen($state)) {\n  // abort with a configuration error instead of letting verifyAuthCSRFCode throw\n}","typeGuard":null,"tryCatchPattern":"try {\n  $provider->verifyAuthCSRFCode($request, $state);\n} catch (Exception $ex) {\n  // treat as a failed handshake: show the provider's login page again with a\n  // 'clear cookies and retry' hint; never loop on automatic retries\n}","preventionTips":["Custom adapters must round-trip the state parameter through the IdP untouched.","Verify proxy/CDN rules preserve query parameters on the callback path.","Test the full handshake after any provider config change, not just the initial redirect."],"tags":["phabricator","auth","oauth","csrf","state-parameter"],"backgroundTag":"oauth-state-missing","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}