passbolt/passbolt_api · error · BadRequestException

The authentication token is not valid.

Error message

The authentication token is not valid.

What it means

Thrown by assertAuthToken in RecoverStartUserInfoService when AuthenticationTokenGetService::getActiveNotExpiredOrFail finds no active, unexpired RECOVER token for the given token id and user id. The recover start step requires proof of a valid token before disclosing user info.

Solutions

  1. Restart the recovery process to generate and receive a fresh RECOVER token, then use the new link
  2. Verify the token row: type=RECOVER, active=1, and not expired, and that user_id matches the URL user id
  3. Make sure you are using the recover link, not the initial setup/invite link
  4. Check clock/timezone skew is not expiring tokens prematurely on the server
Defensive patterns

Strategy: validation

Validate before calling

const t = await getTokenRow(tokenId);
const valid = t && t.type === 'recover' && t.active && new Date(t.expired) > new Date() && t.user_id === userId;

Try / catch

try { const info = await recoverStartInfo(userId, token, data); }
catch (e) { if (isInvalidToken(e)) startNewRecoveryFlow(userId); else throw e; }

Prevention

When it happens

Trigger: Calling recover start with an expired token, an already-consumed token, a token of the wrong type (e.g. REGISTER instead of RECOVER), a token belonging to a different user, or a bogus token id.

Common situations: Clicking an old recover email after requesting a newer one; waiting past the token expiry window; mixing up setup (registration) and recover token links; hand-copying the token id with truncation/extra characters.

Understand the failure class

Related errors


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

Appendix: source

Thrown at src/Service/Setup/RecoverStartUserInfoService.php:62

        return $data;
    }

    /**
     * Find the recover token
     *
     * @param string $token uuid of the token
     * @param \App\Model\Entity\User $user user attempting to recover
     * @return void
     * @throw Custom if the token is not valid
     * @throw BadRequestException if the token is not valid
     */
    private function assertAuthToken(string $token, User $user): void
    {
        try {
            (new AuthenticationTokenGetService())
                ->getActiveNotExpiredOrFail($token, $user->id, AuthenticationToken::TYPE_RECOVER);
        } catch (NotFoundException $exception) {
            throw new BadRequestException(__('The authentication token is not valid.'));
        }
    }
}

View on GitHub (pinned to 31c1bbc10f)