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
- Restart the recovery process to generate and receive a fresh RECOVER token, then use the new link
- Verify the token row: type=RECOVER, active=1, and not expired, and that user_id matches the URL user id
- Make sure you are using the recover link, not the initial setup/invite link
- 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
- Always use the newest recovery email's token
- Check token type (RECOVER, not REGISTER/SETUP)
- Mind the expiry window; restart recovery if it lapsed
- Ensure user id matches the token owner and watch for server clock skew
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
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The authentication token has been expired.
- The authentication token is not valid.
- The authentication token does not exist or has been deleted.
- The authentication token has been expired.
- Ajax/Json request not supported.
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)