passbolt/passbolt_api · error · IdentityProviderException

response->getReasonPhrase()

Error message

response->getReasonPhrase()

What it means

In the same checkResponse(), if the 'error' field exists but is NOT a string (or error_description is missing/not a string), the provider cannot build an AzureException and instead throws the base IdentityProviderException using the HTTP reason phrase, status code, and raw body. The message equals the HTTP reason phrase (e.g. 'Bad Request').

Solutions

  1. Inspect the chained body/status in the exception to see the raw response
  2. Check for proxies/WAFs rewriting responses on the server's network
  3. Confirm the token endpoint URL is correct (v2.0) and reachable via curl from the server
  4. Retry later if it is a transient Azure-side incident
Defensive patterns

Strategy: try-catch

Validate before calling

// reachability probe before SSO flows
curl -sS -o /dev/null -w '%{http_code}' https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration

Try / catch

try { $token = $provider->getAccessToken('authorization_code', ['code' => $code]); } catch (IdentityProviderException $e) { Log::error('Raw IdP response: ' . $e->getBody()); return $this->respondError(502, 'Identity provider returned an unexpected response.'); }

Prevention

When it happens

Trigger: Azure (or an intermediary) returns a non-standard error payload — error field is an object/array, or the body is HTML/empty from a proxy — with an HTTP error status.

Common situations: Corporate proxy or WAF intercepting the token request and returning an HTML error page; Azure incident returning malformed JSON; response body truncated; wrong endpoint URL hitting an HTML 404.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltEe/Sso/src/Utility/Azure/Provider/AzureProvider.php:145

     */
    protected function createResourceOwner(array $response, AccessToken $token): ResourceOwnerInterface
    {
        return new AzureResourceOwner($response, $this->emailClaim);
    }

    /**
     * @inheritDoc
     */
    protected function checkResponse(ResponseInterface $response, $data): void
    {
        if (empty($data['error'])) {
            return;
        }

        if (is_string($data['error']) && isset($data['error_description']) && is_string($data['error_description'])) {
            throw new AzureException($data['error'], $data['error_description']);
        } else {
            throw new IdentityProviderException(
                $response->getReasonPhrase(),
                $response->getStatusCode(),
                (string)$response->getBody()
            );
        }
    }

    /**
     * Get JWT verification keys from Azure Active Directory.
     *
     * @return array
     */
    public function getJwtVerificationKeys(): array
    {
        $openIdConfiguration = $this->getOpenIdConfiguration();
        $keysUri = $openIdConfiguration['jwks_uri'];

        $factory = $this->getRequestFactory();

View on GitHub (pinned to 31c1bbc10f)