passbolt/passbolt_api · error · CustomValidationException

The authentication token is not valid.

Error message

The authentication token is not valid.

What it means

getActiveNotExpiredOrFail finds a matching token but, when it is past expiry, marks it inactive, saves, and throws CustomValidationException('The authentication token is not valid.') with a 'token.expired' validation error so clients know the token expired.

Solutions

  1. Request a new token: resend the setup/recover/verify email.
  2. Verify server timezone and token TTL configuration if expiry seems premature.
  3. Show an 'expired link' UI instead of a generic error by inspecting the token.expired error key.
  4. Clean up expired tokens with the standard purge command to keep the table tidy.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    $token = $service->getActiveNotExpiredOrFail($token, $userId, $type);
} catch (CustomValidationException $e) {
    if (isset($e->getErrors()['token']['expired'])) {
        // offer 'resend email' flow
    }
}

Prevention

When it happens

Trigger: Calling getActiveNotExpiredOrFail (via getNotCompletedOrFail) with a token whose expiry timestamp is in the past but that is still active in the DB.

Common situations: User opens a setup/recover email link days after receiving it; tokens left from before a deployment pause; clock/timezone drift making tokens appear expired.

Understand the failure class

Related errors


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

Appendix: source

Thrown at src/Service/AuthenticationTokens/AuthenticationTokenGetService.php:79

     * @throws \Cake\Http\Exception\BadRequestException if token id is not a valid uuid
     */
    public function getActiveNotExpiredOrFail(
        string $token,
        string $userId,
        string $type,
        ?string $expiry = null
    ): AuthenticationToken {
        $tokenEntity = $this->getActiveOrFail($token, $userId, $type);

        if ($tokenEntity->isExpired($expiry)) {
            $tokenEntity->set('active', false);
            $this->AuthenticationTokens->save($tokenEntity);
            $error = [
                'token' => [
                    'expired' => __('The token is expired.'),
                ],
            ];
            throw new CustomValidationException(__('The authentication token is not valid.'), $error);
        }

        return $tokenEntity;
    }

    /**
     * Get active token or fail.
     *
     * @param string $token authentication token
     * @param string $userId user ID
     * @param string $type token type
     * @return \App\Model\Entity\AuthenticationToken
     * @throws \Cake\Http\Exception\NotFoundException if token is not found
     * @throws \App\Error\Exception\CustomValidationException if the token is inactive
     * @throws \Cake\Http\Exception\BadRequestException if token id is not a valid uuid
     */
    public function getActiveOrFail(string $token, string $userId, string $type): AuthenticationToken
    {

View on GitHub (pinned to 31c1bbc10f)