passbolt/passbolt_api · error · BadRequestException
The state is required in URL parameters.
Error message
The state is required in URL parameters.
What it means
The SSO callback requires a 'state' query parameter that must pass SsoState::isValidState(). If it is absent, not a string, or structurally invalid, the controller cannot proceed with the CSRF check and throws this 400.
Solutions
- Compare the redirect URL the provider sent against the one passbolt generated in stage1 — the state must be echoed verbatim.
- Fix the provider app configuration so the full callback URL (including state) is preserved on redirect.
- Restart the SSO flow to get a fresh state; do not hand-craft the callback URL.
- Check for middleware/proxy rewriting or decoding the query string (e.g. double URL-decoding corrupts the state).
Defensive patterns
Strategy: validation
Validate before calling
const state = new URL(callbackUrl).searchParams.get('state');
if (typeof state !== 'string' || state.length === 0) { throw new Error('Provider did not echo back the state parameter'); } Type guard
function hasStateParam(url) { const s = new URL(url).searchParams.get('state'); return typeof s === 'string' && s.length > 0; } Try / catch
try { await ssoCallback(url); } catch (e) { if (e.status === 400 && /state is required in URL/.test(e.message)) { checkProviderStateEcho(); restartFlow(); } else { throw e; } } Prevention
- Ensure the IdP app passes through the state parameter on redirect
- Do not modify or truncate the callback URL
- Watch for middleware double-decoding the query string
When it happens
Trigger: GET to an SSO callback endpoint without ?state=... or with a malformed state value, typically when the identity provider does not echo back the state parameter it was given.
Common situations: Misconfigured OAuth2 provider (state not passed through on redirect); URL-encoding stripping/corrupting the state; users editing or shortening the callback URL; provider appending parameters in a way that mangles the query string.
Related errors
- The token is required in URL parameters.
- The code is required in request data.
- The code is required in URL parameters.
- The SSO state is invalid.
- Access to this service requires an invitation. Please…
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/d25c94537fad5e7f.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Sso/src/Controller/AbstractSsoController.php:136
public function getTokenFromUrlQuery(): string
{
$token = $this->request->getQuery('token');
if (!is_string($token) || !OAuthTokenValidation::token($token)) {
throw new BadRequestException(__('The token is required in URL parameters.'));
}
return $token;
}
/**
* @throws \Cake\Http\Exception\BadRequestException if the state is not provided in URL query
* @return string state
*/
public function getStateFromUrlQuery(): string
{
$state = $this->request->getQuery('state');
if (!is_string($state) || !SsoState::isValidState($state)) {
throw new BadRequestException(__('The state is required in URL parameters.'));
}
return $state;
}
/**
* @throws \Cake\Http\Exception\BadRequestException if the code (access token) is not provided in URL query
* @return string code
*/
public function getCodeFromUrlQuery(): string
{
$code = $this->request->getQuery('code');
if (!isset($code) || !is_string($code)) {
throw new BadRequestException(__('The code is required in URL parameters.'));
}
return $code;
}View on GitHub (pinned to 31c1bbc10f)