passbolt/passbolt_api · error · BadRequestException
The Duo state cookie should be a valid UUID.
Error message
The Duo state cookie should be a valid UUID.
What it means
Thrown by DuoSetupCallbackGetController::consumeAndAssertCookieToken when the Duo state cookie value is a string but fails Cake's Validation::uuid() check. The state token is generated as a UUID and must round-trip unchanged; any corruption or forgery is rejected.
Solutions
- Clear the MFA Duo cookies and restart the Duo setup flow to get a fresh UUID state cookie.
- Check no proxy or middleware truncates or encodes the Cookie header.
- Do not manually set or edit passbolt MFA cookies; let the server generate them.
- If reproducible, verify Validation::uuid() format expectations against the cookie value logged in the request.
Defensive patterns
Strategy: validation
Validate before calling
const uuidRe = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (!uuidRe.test(cookies.passbolt_mfa_duo_state ?? '')) { throw new Error('Duo state cookie is not a valid UUID; restart flow.'); } Type guard
function isValidUuid(value: unknown): value is string {
return typeof value === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
} Try / catch
try {
await callbackDuoSetup();
} catch (e) {
if (e.status === 400 && /valid UUID/.test(e.message)) {
clearMfaCookies(); restartDuoSetupFlow();
} else { throw e; }
} Prevention
- Restart the flow instead of reusing or hand-editing state cookies.
- Check intermediaries do not truncate the Cookie header.
- Verify cookie values survive URL round-trips without being mangled.
- Log the cookie value when debugging to spot corruption early.
When it happens
Trigger: GET /mfa/duo/setup/callback with a state cookie containing a non-UUID string: truncated value, URL-encoded/decoded variant, hand-crafted value, or value from an unrelated cookie.
Common situations: Cookie truncated by intermediary proxies with header size limits; manual cookie manipulation during debugging; copy-pasted callback URLs with altered cookie values; old cookies left from a differently formatted flow.
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
- The authentication token should be a valid UUID.
- The Duo state cookie should be a valid UUID.
- The authentication token should be a valid UUID.
- The authentication token should be a valid UUID.
- The authentication token should be a valid UUID.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/d8cf40e2b9de546f.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/MultiFactorAuthentication/src/Controller/Duo/DuoSetupCallbackGetController.php:196
*
* @return string The token id stored in the cookie
* @throws \Cake\Http\Exception\BadRequestException if the cookie is not defined
* @throws \Cake\Http\Exception\BadRequestException if the cookie value is not a string
* @throws \Cake\Http\Exception\BadRequestException if the cookie value is not a valid uuid
*/
private function consumeAndAssertCookieToken(): string
{
$cookieToken = (new MfaDuoStateCookieService())->readDuoStateCookieValue($this->getRequest());
if (is_null($cookieToken)) {
throw new BadRequestException(__('A Duo state cookie is required.'));
}
$cookieToExpire = new Cookie(MfaDuoStateCookieService::MFA_COOKIE_DUO_STATE);
$this->setResponse($this->getResponse()->withExpiredCookie($cookieToExpire));
if (!is_string($cookieToken)) {
throw new BadRequestException(__('The Duo state cookie value should be a string.'));
} elseif (!Validation::uuid($cookieToken)) {
throw new BadRequestException(__('The Duo state cookie should be a valid UUID.'));
}
return $cookieToken;
}
/**
* Add to the response the MFA verified cookie.
*
* @param \App\Utility\UserAccessControl $uac User access control
* @param \App\Authenticator\SessionIdentificationServiceInterface $sessionIdentificationService session ID service
* @return void
* @throws \Cake\Http\Exception\InternalErrorException if it cannot create MFA cookie
*/
private function addMfaVerifiedCookieToResponse(
UserAccessControl $uac,
SessionIdentificationServiceInterface $sessionIdentificationService
): void {
try {View on GitHub (pinned to 31c1bbc10f)