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

  1. Access the endpoint via a normal browser navigation/redirect, not an Ajax/fetch call
  2. Remove the Accept: application/json header (or send Accept: text/html) when testing with curl/Postman
  3. Open the recovery link received by email in a browser so the SSO redirect chain completes natively
  4. 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

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


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,
                $e

View on GitHub (pinned to 31c1bbc10f)