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

Thrown when the SSO_RECOVER authentication token in the URL query is not found as an active, non-expired token; the RecordNotFoundException from SsoAuthenticationTokenGetService::getActiveNotExpiredOrFail is wrapped in this BadRequestException by the OAuth2 recover-success controller.

Solutions

  1. Restart the SSO recovery flow to obtain a new token and use the fresh link once only.
  2. Check the token parameter for truncation or encoding issues in the URL.
  3. Ensure the request goes to the same passbolt instance that issued the token.
  4. Do not refresh or re-open the success URL after it has completed; the token is single-use.
Defensive patterns

Strategy: try-catch

Validate before calling

const token = new URLSearchParams(window.location.search).get('token');
if (!token || /\s/.test(token)) console.warn('SSO recover token missing or malformed; restart the flow.');

Type guard

function hasToken(url) {
  const t = new URL(url, window.location.origin).searchParams.get('token');
  return typeof t === 'string' && t.length >= 16;
}

Try / catch

try {
  await completeOauth2SsoRecoverSuccess(token);
} catch (e) {
  if (e.message.includes('does not exist or has been deleted')) {
    restartSsoRecoverFlow(); // token single-use; get a new one
  }
}

Prevention

When it happens

Trigger: GET /sso/recover/success?token=... where the token matches no active record: already consumed by a previous success request, deleted, mistyped/truncated, or issued by another environment.

Common situations: Double-submission or refresh of the success page after the single-use token was consumed; replaying an expired recovery link; migrating between instances mid-recovery.

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/98b4515fe7e45b2b. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/SsoRecover/src/Controller/OAuth2/OAuth2RecoverSuccessController.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)