passbolt/passbolt_api · error · BadRequestException

The authentication token has been expired.

Error message

The authentication token has been expired.

What it means

Thrown when the SSO recover token exists but the SsoAuthenticationTokenGetService determined it is no longer active/valid (CustomValidationException from getActiveNotExpiredOrFail, i.e. expired or in an inactive state). The controller maps that to this BadRequestException.

Solutions

  1. Restart the recover flow to generate a new token and complete the OAuth redirect promptly within the token lifetime.
  2. Complete the flow in a single session without long pauses between the login start and provider callback.
  3. Verify server clocks are synchronized (NTP) and the app timezone settings are correct.
  4. If tokens expire too quickly for your users, review the SSO token expiry configuration.
Defensive patterns

Strategy: try-catch

Validate before calling

// Check token age client-side if the issue time is known
const elapsedMin = (Date.now() - tokenIssuedAtMs) / 60000;
if (elapsedMin > TOKEN_TTL_MINUTES) await restartSsoRecoverFlow();

Try / catch

try {
  await completeSsoRecoverSuccess(token);
} catch (e) {
  if (e.message.includes('has been expired')) {
    await restartSsoRecoverFlow(); // obtain a fresh token
  }
}

Prevention

When it happens

Trigger: GET /sso/recover/success/azure?token=... where the token's created/expiry timestamp is past the SSO authentication token lifetime, or the token was deactivated after a failed/completed recover attempt.

Common situations: User waits too long between starting the SSO recovery and completing the OAuth redirect (token TTL elapsed), leaves the recovery tab open overnight, or the server clock/timezone is misconfigured causing premature expiry.

Understand the failure class

Related errors


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

Appendix: source

Thrown at plugins/PassboltEe/SsoRecover/src/Controller/Azure/AzureRecoverSuccessController.php:62

    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)