phacility/phabricator · error · Exception

The authentication provider did not return a client state pa

Error message

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.

What it means

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.

Source

Thrown at src/applications/auth/provider/PhabricatorAuthProvider.php:566

    if (!strlen($phcid)) {
      throw new AphrontMalformedRequestException(
        pht('Missing Client ID Cookie'),
        pht(
          'Your browser did not submit a "%s" cookie with client state '.
          'information in the request. Check that cookies are enabled. '.
          'If this problem persists, you may need to clear your cookies.',
          PhabricatorCookies::COOKIE_CLIENTID),
        true);
    }

    return PhabricatorHash::weakDigest($phcid);
  }

  protected function verifyAuthCSRFCode(AphrontRequest $request, $actual) {
    $expect = $this->getAuthCSRFCode($request);

    if (!strlen($actual)) {
      throw new Exception(
        pht(
          '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.'));
    }

    if (!phutil_hashes_are_identical($actual, $expect)) {
      throw new Exception(
        pht(
          'The authentication provider did not return the correct client '.
          'state parameter in its response. If this problem persists, you may '.
          'need to clear your cookies.'));
    }
  }

  public function supportsAutoLogin() {
    return false;
  }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Confirm the authorization request Phabricator sends actually includes state, and that the IdP echoes it back on the exact registered callback URL.
  2. 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.
  3. Check reverse proxies / CDNs / rewrite rules between the IdP and Phabricator for query-string stripping, and bypass or fix them for the callback path.
  4. Have the user retry from a fresh login (clearing stale cookies), since the accompanying advice also applies when the phcid-side state expired.
Defensive patterns

Strategy: try-catch

Validate before calling

// In a custom adapter, never dispatch a callback with an empty state
if (!strlen($state)) {
  // abort with a configuration error instead of letting verifyAuthCSRFCode throw
}

Try / catch

try {
  $provider->verifyAuthCSRFCode($request, $state);
} catch (Exception $ex) {
  // treat as a failed handshake: show the provider's login page again with a
  // 'clear cookies and retry' hint; never loop on automatic retries
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/50e86e2376dfcd5c. Report an issue: GitHub.