passbolt/passbolt_api · error · BadRequestException
The authentication token does not exist.
Error message
The authentication token does not exist.
What it means
In SsoKeysGetService::get(), the SSO authentication token is fetched via SsoAuthenticationTokenGetService::getOrFail(); if the token record does not exist, RecordNotFoundException('The authentication token does not exist.') is re-thrown as BadRequestException. The token is the secret handed to the browser during the SSO key exchange and must exist (and later pass assertAndConsume) before the SSO key is returned.
Solutions
- Restart the SSO login/key-exchange flow from the beginning so a fresh token is generated
- Do not reuse a token once the SSO key was fetched — each token is single-use
- Check the sso_authentication_tokens table to confirm the token id exists
- Ensure the client is not double-submitting the request (e.g. retries after a timeout)
Example fix
// before: reuse consumed token on page refresh
await getSsoKey(oldTokenId);
// after: restart flow to obtain a new token
const {token} = await startSsoKeyExchange();
await getSsoKey(token); Defensive patterns
Strategy: try-catch
Validate before calling
// check token exists and is unconsumed before calling
$token = $SsoAuthTokens->find()->where(['id' => $tokenId, 'active' => true])->first();
if (!$token) {
restartSsoFlow();
} Try / catch
try {
$key = $ssoKeysGetService->get($uac, $token, $keyId);
} catch (BadRequestException $e) {
if (str_contains($e->getMessage(), 'authentication token does not exist')) {
return $this->restartSsoFlow(); // token used/expired
}
throw $e;
} Prevention
- Treat SSO tokens as single-use; never reuse after a successful fetch
- Avoid re-submitting the same request on page refresh or network retry
- Restart the whole SSO flow when a token is rejected
When it happens
Trigger: Calling the SSO keys get endpoint with a token id that was never created, was already consumed by a prior call (assertAndConsume consumes it), or expired/was deleted.
Common situations: Replaying an SSO key-exchange token after it was already used in a previous request; browser refresh re-submitting a used token; clocks/expiry cleanup removing the token; copy-pasting a token from another session.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The SSO state does not exist.
- It is not possible to create an authentication token for…
- The authentication token does not exist.
- The authentication token does not exist or has been deleted.
- The authentication token does not exist or has been deleted.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/2aeeba863a044a0a.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Sso/src/Service/SsoKeys/SsoKeysGetService.php:50
*
* @param \App\Utility\ExtendedUserAccessControl $uac extended user access control
* @param string $token SsoAuthenticationToken.token
* @param string $keyId uuid
* @return \Passbolt\Sso\Model\Entity\SsoKey
*/
public function get(ExtendedUserAccessControl $uac, string $token, string $keyId): SsoKey
{
try {
$ssoSettingEntity = (new SsoSettingsGetService())->getActiveOrFail();
// Token must be provided and matching the settings, user id, ip, user agent, etc.
$ssoAuthTokenGetService = new SsoAuthenticationTokenGetService();
$ssoAuthToken = $ssoAuthTokenGetService->getOrFail(
$token,
SsoState::TYPE_SSO_GET_KEY
);
$ssoAuthTokenGetService->assertAndConsume($ssoAuthToken, $uac, $ssoSettingEntity->id);
} catch (RecordNotFoundException $exception) {
throw new BadRequestException($exception->getMessage(), 400, $exception);
}
try {
$SsoKeys = TableRegistry::getTableLocator()->get('Passbolt/Sso.SsoKeys');
/** @var \Passbolt\Sso\Model\Entity\SsoKey $key entity */
$key = $SsoKeys->find()->where(['id' => $keyId, 'user_id' => $uac->getId()])->firstOrFail();
} catch (RecordNotFoundException $exception) {
throw new RecordNotFoundException(__('The SSO key does not exist.'), 404, $exception);
}
return $key;
}
}
View on GitHub (pinned to 31c1bbc10f)