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

MfaDuoEnableService::enable performs the same UUID pre-validation as the callback token service: the $token argument must be a valid UUID before it is forwarded to MfaDuoCallbackAuthenticationTokenService::consumeAndVerifyAuthenticationToken. A non-UUID token is rejected with this InvalidArgumentException without any database lookup.

Solutions

  1. Pass the UUID token issued when the Duo setup flow started (AuthenticationToken::TYPE_MFA_SETUP token)
  2. Validate with Validation::uuid($token) in the caller before calling enable()
  3. Fix the callback controller mapping so the passbolt token parameter — not the Duo code — is passed as $token
  4. If the token was lost, restart the Duo setup flow to get a new one

Example fix

// before
(new MfaDuoEnableService())->enable($uac, $dto, $duoCallbackDto->duoCode); // wrong value
// after
(new MfaDuoEnableService())->enable($uac, $duoCallbackDto, $mfaSetupTokenUuid);
Defensive patterns

Strategy: validation

Validate before calling

if (!\Cake\Validation\Validation::uuid($token)) {
    throw new \Cake\Http\Exception\BadRequestException('MFA setup token must be a UUID.');
}

Try / catch

try {
    $service->enable($uac, $dto, $token);
} catch (\InvalidArgumentException $e) {
    throw new \Cake\Http\Exception\BadRequestException($e->getMessage());
}

Prevention

When it happens

Trigger: Calling enable() with a token string that is not a UUID — empty string, garbage from a tampered callback URL, or the Duo authorization code passed where the passbolt setup token was expected.

Common situations: Mixing up the Duo 'code' parameter with the passbolt MFA token in the callback handler; client sends the token URL-decoded/truncated; a test passes a placeholder token string like 'test-token'.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltCe/MultiFactorAuthentication/src/Service/Duo/MfaDuoEnableService.php:83

     * Enable 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.
     * @throws \Cake\Http\Exception\InternalErrorException if the Duo provider cannot be enabled for the user.
     */
    public function enable(
        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_SETUP;
        $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);
        }
        $this->enableProvider($uac);

        return $authenticationToken;

View on GitHub (pinned to 31c1bbc10f)