passbolt/passbolt_api · warning · BadRequestException
The SSO state type is invalid.
Error message
The SSO state type is invalid.
What it means
Thrown in the default arm of the switch in stage2 of the SSO controller when the SSO state's type is not one of the recognized values (e.g. the expected mfa/recover/register/login state types). The state cookie is exchanged for an SsoState entity, and its 'type' field must match a branch the controller knows how to handle. This is a server-side guard against corrupted or forged state cookies.
Solutions
- Clear the passbolt SSO state cookie in the browser and restart the SSO flow from the beginning (login/recover/register).
- Inspect the SsoState entity produced from the cookie (plugins/PassboltEe/Sso) and confirm the 'type' value matches one of the SsoState::TYPE_* constants handled in stage2.
- Verify the browser is using the correct server version — mismatched plugin versions can produce unknown state types; run 'ddev refresh' to sync migrations and cache.
- Check for a proxy/CDN serving an old cached callback page with an outdated state.
Defensive patterns
Strategy: validation
Validate before calling
const stateTypes = ['mfa','recover','register','login'];
if (!stateTypes.includes(ssoState.type)) { throw new Error('Unsupported SSO state type: ' + ssoState.type); } Type guard
function isKnownSsoStateType(t) { return typeof t === 'string' && ['mfa','recover','register','login'].includes(t); } Try / catch
try { await completeStage2(state); } catch (e) { if (e.status === 400 && /state type is invalid/.test(e.message)) { clearSsoCookies(); restartSsoFlow(); } else { throw e; } } Prevention
- Always restart the full SSO flow rather than reusing old callback URLs
- Clear passbolt SSO cookies when upgrading server versions
- Avoid multiple concurrent SSO flows in the same browser
When it happens
Trigger: A user hits the SSO stage2 callback URL with a state cookie whose decrypted SsoState entity carries a 'type' value outside the set the switch statement handles (e.g. an old or invalid serialized state).
Common situations: Stale SSO cookies left over from a previous passbolt version whose state type no longer exists; a truncated/corrupted cookie; a user replaying an old callback URL with a cookie from a different flow; plugin upgrades between CE/EE SSO v1 and v2 that changed state types.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- The SSO state is invalid.
- Ajax/Json request not supported.
- Ajax/Json request not supported.
- Ajax/Json request not supported.
- Ajax/Json request not supported.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/4bd531eebd1c36d7.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Sso/src/Controller/AbstractSso2Stage2Controller.php:199
$code,
$this->User->ip(),
$this->User->userAgent(),
$this->getProviderName()
);
} catch (Exception $e) {
$event = new Event(self::EVENT_PROVIDER_ERROR_RESOURCE_OWNER, $this, ['exception' => $e]);
$this->getEventManager()->dispatch($event);
// To map 500(internal error/provider specific exceptions) to 4xx exception
if (isset($event->getResult()['customException'])) {
$e = $event->getResult()['customException'];
}
throw $e;
}
break;
default:
throw new BadRequestException(__('The SSO state type is invalid.'));
}
$this->response = $this->getResponse()->withCookie($service->clearStateCookie());
$this->redirect($successUrl);
}
/**
* @param \App\Service\Cookie\AbstractSecureCookieService $cookieService Cookie service
* @param \Passbolt\Sso\Model\Entity\SsoState $ssoState SSO state.
* @param string $code jwt
* @return void
*/
protected function stage2AsAdmin(AbstractSecureCookieService $cookieService, SsoState $ssoState, string $code): void
{
try {
// Get the draft settings
$settingsDto = (new SsoSettingsGetService())->getDraftByIdOrFail($ssoState->sso_settings_id, true);
} catch (Exception $exception) {View on GitHub (pinned to 31c1bbc10f)