BookStackApp/BookStack · error · OidcIssuerDiscoveryException
Error discovering provider settings from issuer at URL {$iss
Error message
Error discovering provider settings from issuer at URL {$issuerUrl} What it means
loadSettingsFromIssuerDiscovery() throws this when the response from {issuer}/.well-known/openid-configuration is empty, is not valid JSON, or does not decode to an array. The library therefore received *a* HTTP response but it wasn't a usable discovery document.
Source
Thrown at app/Access/Oidc/OidcProviderSettings.php:122
$this->applySettingsFromArray($discoveredSettings);
} catch (ClientExceptionInterface $exception) {
throw new OidcIssuerDiscoveryException("HTTP request failed during discovery with error: {$exception->getMessage()}");
}
}
/**
* @throws OidcIssuerDiscoveryException
* @throws ClientExceptionInterface
*/
protected function loadSettingsFromIssuerDiscovery(ClientInterface $httpClient): array
{
$issuerUrl = rtrim($this->issuer, '/') . '/.well-known/openid-configuration';
$request = new Request('GET', $issuerUrl);
$response = $httpClient->sendRequest($request);
$result = json_decode($response->getBody()->getContents(), true);
if (empty($result) || !is_array($result)) {
throw new OidcIssuerDiscoveryException("Error discovering provider settings from issuer at URL {$issuerUrl}");
}
if ($result['issuer'] !== $this->issuer) {
throw new OidcIssuerDiscoveryException('Unexpected issuer value found on discovery response');
}
$discoveredSettings = [];
if (!empty($result['authorization_endpoint'])) {
$discoveredSettings['authorizationEndpoint'] = $result['authorization_endpoint'];
}
if (!empty($result['token_endpoint'])) {
$discoveredSettings['tokenEndpoint'] = $result['token_endpoint'];
}
if (!empty($result['userinfo_endpoint'])) {
$discoveredSettings['userinfoEndpoint'] = $result['userinfo_endpoint'];View on GitHub (pinned to 18f8469a1c)
Solutions
- curl the discovery URL from the server and inspect the raw body — it must be JSON with issuer, endpoints and jwks_uri.
- Correct OIDC_ISSUER so it points to the actual OIDC issuer (e.g. include the realm path in Keycloak: https://host/realms/<realm>).
- Bypass or authenticate the proxy/WAF intercepting server-to-server requests, or allowlist the BookStack host.
- Verify no redirect to an SSO login page occurs (curl -L and check content-type is application/json).
Example fix
# before OIDC_ISSUER=https://keycloak.example.com # hits portal HTML # after OIDC_ISSUER=https://keycloak.example.com/realms/main # serves JSON discovery
Defensive patterns
Strategy: type-guard
Validate before calling
$raw = file_get_contents(rtrim(config('oidc.issuer'), '/') . '/.well-known/openid-configuration');
$doc = json_decode($raw ?? '', true);
if (!is_array($doc) || empty($doc['issuer'])) {
throw new RuntimeException('Discovery endpoint did not return a JSON document');
} Type guard
function isValidDiscoveryDoc(?array $decoded): bool {
return is_array($decoded)
&& isset($decoded['issuer'], $decoded['authorization_endpoint'], $decoded['token_endpoint']);
} Try / catch
try {
$settings->discoverFromIssuer($client, $cache, 15);
} catch (OidcIssuerDiscoveryException $e) {
if (str_contains($e->getMessage(), 'Error discovering provider settings')) {
Log::error('Discovery response was not JSON — check issuer URL / auth walls: ' . $e->getMessage());
}
} Prevention
- Point the issuer at the real OIDC issuer path, not a portal URL that serves HTML.
- Allowlist the BookStack server in any WAF/auth-wall in front of the IdP.
- curl -i the discovery URL and confirm content-type application/json before deploying.
- Watch for redirects to SSO sign-in pages when fetching discovery server-side.
When it happens
Trigger: The discovery URL returns 200 with non-JSON content (HTML login/error page, empty body, proxy interstitial), or the request was redirected to an SSO sign-in page that returns HTML with status 200.
Common situations: Issuer URL wrong so a web server's default page/404 HTML is returned; an auth wall or WAF intercepting the request; gzip/misconfigured proxy returning garbage; hitting a human-facing portal path instead of the real OIDC issuer.
Related errors
- HTTP request failed during discovery with error: {$exception
- Error reading keys from issuer jwks_uri
- OIDC Discovery Error:
- Unexpected issuer value found on discovery response
- errors.ldap_cannot_connect
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/4dbfb759a3f05ff1.
Report an issue: GitHub.