passbolt/passbolt_api · error · BadRequestException

The SSO authentication token is invalid. Settings mismatch.

Error message

The SSO authentication token is invalid. Settings mismatch.

What it means

The SSO authentication token records the SSO settings id it was issued for. assertAndConsume() compares that stored settings id with the settings id passed by the caller and also validates it is a UUID; on mismatch it throws BadRequestException with 'Settings mismatch.' This prevents a token minted for one SSO provider configuration (e.g. Azure AD) from being redeemed against another (e.g. Google).

Solutions

  1. Restart the SSO login flow so the token is issued for the current, active SSO settings id
  2. Verify the sso_settings_id in the sso_authentication_tokens data matches the settings row actually in use
  3. Check the sso_settings table for duplicate/rotated configurations and point users at the active one
  4. In tests/integrations, pass the same SsoSetting entity id that was used at token creation

Example fix

// before: token issued for settings A, redeemed against regenerated settings B
$ssoAuthTokenGetService->assertAndConsume($token, $uac, $newSettingsEntity->id);
// after: restart the flow, then redeem with the settings id the token was issued for
$token = $this->SsoAuthenticationTokenGetService->getOrFail($tokenId, SsoState::TYPE_SSO_GET_KEY);
$this->SsoAuthenticationTokenGetService->assertAndConsume($token, $uac, $originalSettingsId);
Defensive patterns

Strategy: validation

Validate before calling

// confirm token/settings pairing before consuming
$tokenData = $token->getDataProperty(SsoAuthenticationToken::DATA_SSO_SETTINGS_ID);
if ($tokenData !== $settingsId || !Validation::uuid($settingsId)) {
    restartSsoFlow();
}

Try / catch

try {
    $service->assertAndConsume($token, $uac, $settingsId);
} catch (BadRequestException $e) {
    if (str_contains($e->getMessage(), 'Settings mismatch')) {
        return $this->restartSsoFlow(); // re-issue token for active settings
    }
    throw $e;
}

Prevention

When it happens

Trigger: Redeeming an SSO token via assertAndConsume() when the token's sso_settings_id differs from the $ssoSettingEntity->id passed in (e.g. SsoKeysGetService::get() with a settings entity whose id no longer matches the token), or when the stored settings id fails UUID validation.

Common situations: Admin re-created or regenerated the SSO settings between the two legs of the login flow, so the old token points at a deleted/rotated settings id; environment data mismatch (token created on staging env data, redeemed on another); passing the wrong settings entity to the service.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltEe/Sso/src/Service/SsoAuthenticationTokens/SsoAuthenticationTokenGetService.php:211

            if ($ip !== $uac->getUserIp()) {
                throw new BadRequestException($errorMsg . __('User IP mismatch.'));
            }
        }

        if (Configure::read('passbolt.security.userAgent')) {
            try {
                $ua = $token->getDataProperty(SsoAuthenticationToken::DATA_USER_AGENT);
            } catch (AuthenticationTokenDataPropertyException $exception) {
                throw new BadRequestException($errorMsg . __('User agent is missing.'), 400, $exception);
            }
            if ($ua !== $uac->getUserAgent()) {
                throw new BadRequestException($errorMsg . __('User agent mismatch.'));
            }
        }

        if ($sid !== $settingsId || !Validation::uuid($sid)) {
            throw new BadRequestException($errorMsg . __('Settings mismatch.'));
        }
    }
}

View on GitHub (pinned to 31c1bbc10f)