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

MfaDuoStateCookieService::createDuoStateCookie() stores the mfa authentication token id (Duo state) in an HttpOnly secure cookie. It validates the token is a UUID and throws an InvalidArgumentException otherwise, so a corrupt state cookie is never emitted.

Solutions

  1. Pass the generated AuthenticationToken id (UUID) from the Duo start flow
  2. Validate with Validation::uuid($token) before calling
  3. Ensure the value comes from the token object, not user-controlled input

Example fix

// before
$cookieService->createDuoStateCookie($this->request->getQuery('state'), true);
// after
$token = $authenticationToken->id; // valid UUID from generate()
$cookieService->createDuoStateCookie($token, true);
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 { $cookie = $cookieService->createDuoStateCookie($token, $secure); } catch (\InvalidArgumentException $e) { /* return 400; token must come from start() */ }

Prevention

When it happens

Trigger: Calling createDuoStateCookie($token, $secure) with a token that is not a valid UUID — empty string, truncated id, or a non-token value.

Common situations: Custom controllers passing a session key instead of the AuthenticationToken id; token value taken from a mangled query parameter; test code passing placeholder strings.

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.

Related errors


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

Appendix: source

Thrown at plugins/PassboltCe/MultiFactorAuthentication/src/Service/Duo/MfaDuoStateCookieService.php:55

    /**
     * Passbolt temporary cookie expiry in minutes
     *
     * @var int
     */
    public const MFA_COOKIE_DUO_STATE_EXPIRY_IN_MINUTES = 10;

    /**
     * Create a Duo state cookie.
     *
     * @param string $token Authentication token's token
     * @param bool $secure Whether to set the cookie as secure
     * @return \Cake\Http\Cookie\Cookie The created cookie containing the Duo state value
     */
    public function createDuoStateCookie(string $token, bool $secure): Cookie
    {
        if (!Validation::uuid($token)) {
            throw new InvalidArgumentException('The authentication token should be a valid UUID.');
        }

        return (new Cookie(self::MFA_COOKIE_DUO_STATE))
            ->withValue($token)
            ->withPath('/')
            ->withHttpOnly(true)
            ->withSecure($secure)
            ->withExpiry((new DateTime())->addMinutes(self::MFA_COOKIE_DUO_STATE_EXPIRY_IN_MINUTES));
    }

    /**
     * Read the Duo state cookie.
     *
     * @param \Cake\Http\ServerRequest $request Server request
     * @return array|string|null The cookie value
     */
    public function readDuoStateCookieValue(ServerRequest $request): array|string|null
    {

View on GitHub (pinned to 31c1bbc10f)