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 from the URL query is not found as an active token; getActiveNotExpiredOrFail raised RecordNotFoundException and the controller wraps it in this BadRequestException. Tokens are single-use, so a missing token usually means it was already consumed or never existed.

Solutions

  1. Restart the SSO recovery flow to receive a fresh token and use the new link exactly once.
  2. Verify the token parameter is complete and unaltered (URL-encoding, email client truncation).
  3. Confirm the request targets the same passbolt instance that issued the token.
  4. Avoid refreshing/re-submitting the success page; the token is consumed on first successful use.
Defensive patterns

Strategy: try-catch

Validate before calling

const token = new URL(location.href).searchParams.get('token');
if (!token) throw new Error('Cannot complete Google SSO recovery: token query parameter missing.');

Type guard

function tokenLooksValid(url) {
  const t = new URL(url).searchParams.get('token');
  return typeof t === 'string' && t.length >= 16 && !/\s/.test(t);
}

Try / catch

try {
  await completeGoogleSsoRecoverSuccess(token);
} catch (e) {
  if (e.message.includes('does not exist or has been deleted')) {
    restartSsoRecoverFlow(); // single-use token gone: start over
  }
}

Prevention

When it happens

Trigger: GET /sso/recover/success/google?token=... with a token value matching no record: token consumed by a prior success call, deleted, typo/truncation, or issued by a different instance/database.

Common situations: Refreshing or double-clicking the success URL (second request finds the token already used), replaying an old Google recovery link, switching environments mid-flow.

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/58262000911bc3c3. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/SsoRecover/src/Controller/Google/GoogleRecoverSuccessController.php:56

    }

    /**
     * @return void
     * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
     */
    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)