passbolt/passbolt_api · error · BadRequestException
Unable to authenticate the guest user with the provided…
Error message
Unable to authenticate the guest user with the provided credentials. The registration authentication token is expired.
What it means
This BadRequestException is thrown when the registration authentication token supplied by a guest exists in authentication_tokens but is expired or otherwise inactive. AuthenticationTokenGetService::getActiveNotExpiredOrFail raises CustomValidationException in that case, and the controller appends 'The registration authentication token is expired.' to the base message. It guards the unauthenticated key policy settings endpoint so only holders of a live register token may call it.
Solutions
- Issue a fresh registration token by restarting the user registration / setup invite flow and use the new token.
- Check the token's created date against the expiry window in authentication_tokens to confirm expiry.
- Verify server (and DB) timezone/clock are correct if the token should still be valid.
- Complete registration and call the endpoint as an authenticated user instead of with a token.
Example fix
// before: reusing a days-old setup link GET /user-key-policies/settings?user_id=<uuid>&token=<expired-register-token> // after: regenerate then use the new token GET /user-key-policies/settings?user_id=<uuid>&token=<fresh-register-token>
Defensive patterns
Strategy: validation
Validate before calling
// client-side freshness check: token created within the expiry window
const created = new Date(tokenMeta.created);
const expires = created.getTime() + EXPIRY_MS;
if (Date.now() > expires) throw new Error('register token expired - request a new one'); Try / catch
try {
await get('/user-key-policies/settings', { user_id, token });
} catch (e) {
if (e.status === 400 && /token is expired/.test(e.message)) {
token = await restartRegistrationFlow(user_id); // obtain fresh token and retry once
} else { throw e; }
} Prevention
- Complete the registration/installer flow promptly after receiving the invitation.
- Track the token creation time and refresh it before the expiry window elapses.
- Keep server clocks NTP-synced so valid tokens are not seen as expired.
- Fall back to authenticated access after registration instead of reusing tokens.
When it happens
Trigger: GET /user-key-policies/settings as guest with user_id=<uuid>&token=<uuid> where a register-type token row exists for that user but its expiry (created + AuthenticationToken expiry delta) has passed, or the token is inactive.
Common situations: User delayed completing registration beyond the token lifetime; old setup bookmark reused; server clock skew makes an otherwise valid token appear expired.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The authentication token is not valid or has expired.
- The token should reference an active Duo callback…
- An authentication token should be provided.
- Attempt to access an expired verify token.
- Conflicting authentication parameters, provide…
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/b92eba2a08a2632b.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/UserKeyPolicies/src/Controller/UserKeyPoliciesGetSettingsController.php:121
}
if (!Validation::uuid($authToken)) {
throw new BadRequestException(__('The authentication token must be a valid UUID.'));
}
$errorMsg = __('Unable to authenticate the guest user with the provided credentials.');
try {
(new AuthenticationTokenGetService())
->getActiveNotExpiredOrFail($authToken, $userId, AuthenticationToken::TYPE_REGISTER);
} catch (NotFoundException $exception) {
$errorMsg .= ' ';
$errorMsg .= __('No registration authentication token found for the given user.');
throw new BadRequestException($errorMsg, null, $exception);
} catch (CustomValidationException $exception) {
$errorMsg .= ' ';
$errorMsg .= __('The registration authentication token is expired.');
throw new BadRequestException($errorMsg, null, $exception);
} catch (Exception $exception) {
throw new ForbiddenException($errorMsg, null, $exception); // phpcs:ignore
}
}
}
View on GitHub (pinned to 31c1bbc10f)