passbolt/passbolt_api · error · InvalidArgumentException
The authentication token should be a valid UUID.
Error message
The authentication token should be a valid UUID.
What it means
MfaDuoLoginService::login() requires the mfa_verify authentication token id passed as $token to be a valid UUID. Validation::uuid() rejects anything else, and an InvalidArgumentException is thrown before the token is consumed.
Solutions
- Pass the full authentication token UUID generated during the Duo start flow (AuthenticationToken.id)
- Validate with Validation::uuid($token) (or a regex) before calling login()
- Check that the callback route/query parameter name matches what passbolt emits so the token is not truncated
Example fix
// before
$service->login($uac, $dto, $this->request->getQuery('token'));
// after
$token = $this->request->getQuery('token') ?? '';
if (!Validation::uuid($token)) { throw new BadRequestException('Missing mfa token'); }
$service->login($uac, $dto, $token); Defensive patterns
Strategy: validation
Validate before calling
use Cake\Validation\Validation;
if (!is_string($token) || !Validation::uuid($token)) { throw new \InvalidArgumentException('token must be a UUID'); } Type guard
function isUuid(mixed $v): bool { return is_string($v) && (bool)preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $v); } Try / catch
try { $service->login($uac, $dto, $token); } catch (\InvalidArgumentException $e) { /* return 400 invalid token */ } Prevention
- Carry the token UUID from start() through the callback without truncation
- Validate UUIDs on ingestion of any user-supplied id
When it happens
Trigger: Calling login($uac, $duoCallbackDto, $token) where $token is empty, truncated, url-mangled, or any non-UUID string — commonly a malformed callback query parameter.
Common situations: User bookmarks/pastes a partially truncated callback URL; a reverse proxy or client code mangles the query string; a custom frontend passes a session id instead of the token UUID.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The authentication token should be a valid UUID.
- The authentication token should be a valid UUID.
- The authentication token should be a valid UUID.
- The Duo state cookie should be a valid UUID.
- The Duo state cookie should be a valid UUID.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/5940f529be3b452b.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/MultiFactorAuthentication/src/Service/Duo/MfaDuoLoginService.php:80
/**
* Login using Duo for the operator.
*
* @param \App\Utility\UserAccessControl $uac The user access control
* @param \Passbolt\MultiFactorAuthentication\Model\Dto\MfaDuoCallbackDto $duoCallbackDto The Duo callback data
* @param string $token The authentication token.
* @return \App\Model\Entity\AuthenticationToken
* @throws \InvalidArgumentException if the provided token is not a UUID
* @throws \Cake\Http\Exception\UnauthorizedException If no active Duo callback authentication can be found.
* @throws \Cake\Http\Exception\UnauthorizedException If the duo state cannot be verified.
* @throws \Cake\Http\Exception\UnauthorizedException If the Duo code cannot be verified.
*/
public function login(
UserAccessControl $uac,
MfaDuoCallbackDto $duoCallbackDto,
string $token
): AuthenticationToken {
if (!Validation::uuid($token)) {
throw new InvalidArgumentException('The authentication token should be a valid UUID.');
}
$authenticationTokenType = AuthenticationToken::TYPE_MFA_VERIFY;
$authenticationToken = (new MfaDuoCallbackAuthenticationTokenService())
->consumeAndVerifyAuthenticationToken(
$uac,
$authenticationTokenType,
$token,
$duoCallbackDto->state
);
try {
(new MfaDuoVerifyDuoCodeService($authenticationTokenType, $this->duoClient))
->verify($uac, $duoCallbackDto->duoCode);
} catch (Throwable $th) {
throw new BadRequestException(__('Unable to verify Duo authentication.'), null, $th);
}
return $authenticationToken;
}View on GitHub (pinned to 31c1bbc10f)