passbolt/passbolt_api · error · BadRequestException
Ajax/Json request not supported.
Error message
Ajax/Json request not supported.
What it means
The SSO recover success endpoint is a browser-redirect (web) endpoint that completes a recover flow started via an IdP. It only supports HTML navigation, so any request flagged as JSON/Ajax (Accept: application/json or X-Requested-With) is rejected with a BadRequestException.
Solutions
- Access the endpoint via a normal browser navigation/redirect, not an Ajax/fetch call
- Remove the Accept: application/json header (or send Accept: text/html) when testing with curl/Postman
- Open the recovery link received by email in a browser so the SSO redirect chain completes natively
- In an SPA, perform a full-page redirect (window.location = url) rather than fetching the URL
Example fix
// before (fails) curl -H "Accept: application/json" https://passbolt.example.com/sso/recover/success?token=... // after curl -H "Accept: text/html" -L https://passbolt.example.com/sso/recover/success?token=...
Defensive patterns
Strategy: fallback
Validate before calling
if (isset($_SERVER['HTTP_ACCEPT']) && str_contains($_SERVER['HTTP_ACCEPT'], 'application/json')) {
// do not call the endpoint via JSON; navigate instead
} Try / catch
try {
// full-page navigation to the recover success URL
window.location.href = ssoRecoverSuccessUrl;
} catch (e) {
// fall back to opening in a new tab
window.open(ssoRecoverSuccessUrl, '_blank');
} Prevention
- Never fetch SSO redirect endpoints with fetch/XHR — use top-level navigation
- Omit JSON Accept headers when testing browser-only endpoints with curl/Postman
- Treat /sso/recover/* routes as HTML-only in API clients
- Document this constraint for any automation around recovery
When it happens
Trigger: Calling /sso/recover/success (ADFS flow) with header Accept: application/json, or via fetch/XHR/Ajax instead of letting the browser follow the IdP redirect in a normal navigation.
Common situations: API clients or scripts trying to automate the recover flow over JSON; single-page apps fetching the redirect URL programmatically instead of opening it; curl tests adding -H 'Accept: application/json' (as passbolt's usual JSON API convention suggests).
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Ajax/Json request not supported.
- Ajax/Json request not supported.
- Ajax/Json request not supported.
- The authentication token does not exist or has been deleted.
- Ajax/Json request not supported.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/ca3981d063799192.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/SsoRecover/src/Controller/Adfs/AdfsRecoverSuccessController.php:45
class AdfsRecoverSuccessController extends AbstractSsoController
{
/**
* @inheritDoc
*/
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
$this->Authentication->allowUnauthenticated(['ssoRecoverSuccess']);
}
/**
* @return void
*/
public function ssoRecoverSuccess(): void
{
if ($this->request->is('json')) {
throw new BadRequestException(__('Ajax/Json request not supported.'));
}
$this->User->assertNotLoggedIn();
$token = $this->getTokenFromUrlQuery();
try {
(new SsoAuthenticationTokenGetService())->getActiveNotExpiredOrFail($token, SsoState::TYPE_SSO_RECOVER);
} catch (RecordNotFoundException $e) {
throw new BadRequestException(
__('The authentication token does not exist or has been deleted.'),
null,
$e
);
} catch (CustomValidationException $e) {
throw new BadRequestException(
__('The authentication token has been expired.'),
null,
$eView on GitHub (pinned to 31c1bbc10f)