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

MfaDuoCallbackAuthenticationTokenService::consumeAndVerifyAuthenticationToken validates the raw Duo callback authentication token string before touching the database. If Validation::uuid($token) fails, it throws this InvalidArgumentException immediately, because only UUID-format tokens can be looked up in the authentication_tokens table. It is a cheap pre-condition guard so callers never pass malformed identifiers downstream.

Solutions

  1. Check the token value passed in is a UUID generated by AuthenticationTokenService (e.g. from the /mfa/setup/duo endpoint response)
  2. Validate with \Cake\Validation\Validation::uuid($token) in the caller before invoking the service
  3. Fix the callback controller/route so the passbolt token UUID is extracted from the correct query parameter or path segment
  4. Regenerate the MFA setup token if the original was lost — it is always a UUID

Example fix

// before
$service->consumeAndVerifyAuthenticationToken($uac, $tokenType, $_GET['state'], $state);
// after
$token = $_GET['token'] ?? '';
if (!Validation::uuid($token)) {
    throw new BadRequestException('Missing or malformed MFA token.');
}
$service->consumeAndVerifyAuthenticationToken($uac, $tokenType, $token, $state);
Defensive patterns

Strategy: validation

Validate before calling

if (!\Cake\Validation\Validation::uuid($token)) {
    throw new \Cake\Http\Exception\BadRequestException('A valid MFA token UUID is required.');
}

Try / catch

try {
    $authToken = $service->consumeAndVerifyAuthenticationToken($uac, $type, $token, $state);
} catch (\InvalidArgumentException $e) {
    throw new \Cake\Http\Exception\BadRequestException($e->getMessage());
}

Prevention

When it happens

Trigger: Calling consumeAndVerifyAuthenticationToken() (or MfaDuoEnableService::enable() which forwards the token) with a $token argument that is not a valid UUID — e.g. a truncated token, a JWT, an empty string, or a value tampered with in the Duo callback query string.

Common situations: A developer wires up the Duo callback endpoint and passes the wrong query parameter (e.g. the Duo 'code' or 'state' instead of the passbolt token UUID); a client truncates the token URL; tests hand-craft token strings like 'invalid-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/bd0d971ccdf597e1. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/MultiFactorAuthentication/src/Service/Duo/MfaDuoCallbackAuthenticationTokenService.php:61

     * Consume and verify Duo callback authentication token.
     *
     * @param \App\Utility\UserAccessControl $uac User access control
     * @param string $tokenType AuthenticationToken's token type
     * @param string $token AuthenticationToken's token
     * @param string $duoState The Duo state to verify the token state value against
     * @return \App\Model\Entity\AuthenticationToken
     * @throws \InvalidArgumentException if token is not a valid UUID.
     * @throws \InvalidArgumentException if token type is not supported.
     * @throws \InvalidArgumentException if the Duo state token is not a valid UUID.
     */
    public function consumeAndVerifyAuthenticationToken(
        UserAccessControl $uac,
        string $tokenType,
        string $token,
        string $duoState
    ): AuthenticationToken {
        if (!Validation::uuid($token)) {
            throw new InvalidArgumentException('The authentication token should be a valid UUID.');
        }
        if (!Validation::inList($tokenType, MfaDuoCallbackAuthenticationTokenService::$ALLOWED_TOKEN_TYPES)) {
            $readableAllowedTokenTypes = implode(', ', MfaDuoCallbackAuthenticationTokenService::$ALLOWED_TOKEN_TYPES);
            $msg = 'The authentication token type should be one of the following: ' . $readableAllowedTokenTypes . '.';
            throw new InvalidArgumentException($msg);
        }

        $authToken = $this->consumeAuthenticationTokenOrFail($uac, $tokenType, $token);
        $this->assertDuoStateMatchesAuthenticationTokenState($authToken, $duoState);

        return $authToken;
    }

    /**
     * Consume the duo callback authentication token or fail.
     *
     * @param \App\Utility\UserAccessControl $uac User access control
     * @param string $tokenType AuthenticationToken's token type

View on GitHub (pinned to 31c1bbc10f)