passbolt/passbolt_api · error · BadRequestException

The authentication token does not exist or has been deleted.

Error message

The authentication token does not exist or has been deleted.

What it means

To complete the SSO recover flow the controller looks up the authentication token from the URL query via SsoAuthenticationTokenGetService::getActiveNotExpiredOrFail() restricted to TYPE_SSO_RECOVER. When no matching active, non-expired token row exists, the RecordNotFoundException is converted into this BadRequestException.

Solutions

  1. Restart the recover process from the beginning to generate a fresh SSO recover token and new emailed link
  2. Verify the URL contains the correct, untruncated token id from the latest recover email
  3. Check the authentication_tokens table for the token, its type (sso-recover), and active/expiry status
  4. Ensure the user completes the flow promptly — tokens are single-use and expire
Defensive patterns

Strategy: try-catch

Validate before calling

if (empty($token) || !preg_match('/^[0-9a-f-]{36}$/i', $token)) {
    // malformed/missing token in URL; restart recover flow before calling the endpoint
}

Try / catch

try {
    // complete SSO recover success flow
} catch (\Cake\Http\Exception\BadRequestException $e) {
    if (str_contains($e->getMessage(), 'authentication token does not exist')) {
        // token consumed/deleted: restart the recover process and use the new emailed link
    }
    throw $e;
}

Prevention

When it happens

Trigger: Recover-success URL carries a token that is missing from the database, already consumed/deleted, of the wrong type, or the endpoint is called with a fabricated/empty token.

Common situations: Reusing an SSO recover link after the flow already completed (token deleted on use); user clicking an old recovery email link after a newer recover request invalidated it; DB cleanup purging expired tokens; tampered URL query parameters.

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.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/5ef1273ba68980b0. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/SsoRecover/src/Controller/Adfs/AdfsRecoverSuccessController.php:54

        $this->Authentication->allowUnauthenticated(['ssoRecoverSuccess']);
    }

    /**
     * @return void
     */
    public function ssoRecoverSuccess(): void
    {
        if ($this->request->is('json')) {
            throw new BadRequestException(__('Ajax/Json request not supported.'));
        }

        $this->User->assertNotLoggedIn();
        $token = $this->getTokenFromUrlQuery();

        try {
            (new SsoAuthenticationTokenGetService())->getActiveNotExpiredOrFail($token, SsoState::TYPE_SSO_RECOVER);
        } catch (RecordNotFoundException $e) {
            throw new BadRequestException(
                __('The authentication token does not exist or has been deleted.'),
                null,
                $e
            );
        } catch (CustomValidationException $e) {
            throw new BadRequestException(
                __('The authentication token has been expired.'),
                null,
                $e
            );
        }

        $this->viewBuilder()
            ->setTheme('Passbolt/Sso')
            ->setLayout('default')
            ->setTemplatePath('success')
            ->setTemplate('stage3');
    }

View on GitHub (pinned to 31c1bbc10f)