phacility/phabricator · error · Exception
Expected verifier to finish OAuth handshake!
Error message
Expected verifier to finish OAuth handshake!
What it means
finishOAuthHandshake() requires an oauth_verifier value (RFC 5849 section 2.2) before it will exchange the request token for an access token. getVerifier() returning empty means the provider's redirect back to your callback did not include (or did not preserve) the verifier parameter.
Source
Thrown at src/applications/auth/adapter/PhutilOAuth1AuthAdapter.php:169
pht("Expected '%s' to be '%s'!", 'oauth_callback_confirmed', 'true'));
}
$this->readTokenAndTokenSecret($data);
$authorize_token_uri = new PhutilURI($this->getAuthorizeTokenURI());
$authorize_token_uri->replaceQueryParam('oauth_token', $this->getToken());
return phutil_string_cast($authorize_token_uri);
}
protected function finishOAuthHandshake() {
$this->willFinishOAuthHandshake();
if (!$this->getToken()) {
throw new Exception(pht('Expected token to finish OAuth handshake!'));
}
if (!$this->getVerifier()) {
throw new Exception(pht('Expected verifier to finish OAuth handshake!'));
}
$validate_uri = $this->getValidateTokenURI();
$params = array(
'oauth_verifier' => $this->getVerifier(),
);
list($body) = $this->newOAuth1Future($validate_uri, $params)->resolvex();
$data = id(new PhutilQueryStringParser())->parseQueryString($body);
$this->readTokenAndTokenSecret($data);
$this->handshakeData = $data;
}
private function readTokenAndTokenSecret(array $data) {
$token = idx($data, 'oauth_token');
if (!$token) {View on GitHub (pinned to 5720a38cfe)
Solutions
- Confirm the provider redirects back with both oauth_token and oauth_verifier in the query string (inspect the callback request URL).
- Make sure your code reads oauth_verifier from the request and calls setVerifier() before finishing the handshake.
- Fix any redirect/rewrite rules between the provider and your endpoint that discard query parameters.
- If the provider only supports OAuth 1.0 (no verifier), it cannot be used with this 1.0a-only adapter.
Example fix
// before: handshake finishes without a verifier
$adapter->finishOAuthHandshake();
// after: pass the verifier from the provider callback through
$adapter->setVerifier($request->getStr('oauth_verifier'));
$adapter->finishOAuthHandshake(); Defensive patterns
Strategy: validation
Validate before calling
// Check the callback parameters before finishing the handshake
$verifier = $request->getStr('oauth_verifier');
if (!strlen($verifier)) {
return $this->restartAuthenticateFlow();
}
$adapter->setVerifier($verifier); Try / catch
try {
$adapter->finishOAuthHandshake();
} catch (Exception $ex) {
if (strpos($ex->getMessage(), 'verifier') !== false) {
// Provider redirect lost oauth_verifier; restart the flow.
return $this->restartAuthenticateFlow();
}
throw $ex;
} Prevention
- Inspect the callback URL for oauth_token and oauth_verifier before invoking the finish phase.
- Keep callback URLs parameter-clean (no existing query string) so the provider appends verifier params.
- Avoid redirect chains between provider and app that strip query parameters.
When it happens
Trigger: The provider redirects to the callback without oauth_verifier (plain OAuth 1.0 behavior or a provider quirk); the callback URI was configured in a way that strips query parameters (e.g., a rewrite rule or a redirect chain that drops the query string); setVerifier() was never called with $request->getStr('oauth_verifier') before the handshake completion; the user hit the callback URL manually.
Common situations: Callback URL configured on the provider that already contains a query string so the verifier gets appended incorrectly or dropped; middleware/redirects normalizing the URL and discarding query params; provider implementing OAuth 1.0 instead of 1.0a; direct navigation/bookmark of the callback URI.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Expected '%s' to be '%s'!
- Expected token to finish OAuth handshake!
- Expected '%s' in response!
- Expected '%s' in request!
- Access token error: %s
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/b9d628d97151a0c5.
Report an issue: GitHub.