passbolt/passbolt_api · error · InternalErrorException
No JWT key defined for Azure service.
Error message
No JWT key defined for Azure service.
What it means
Thrown by AzureProvider::parseJwksKeys after iterating all JWKS key entries when no verification key could be built ($keys is empty). Every key entry lacked a usable 'x5c' array (or the x5c loop produced nothing), so there is no key to verify Azure-issued JWTs and SSO cannot proceed.
Solutions
- Inspect the JWKS response (curl the jwks_uri) and confirm key entries include an 'x5c' array with base64 DER certificates.
- Ensure the OpenID configuration points at the correct Azure AD tenant/common discovery document whose jwks_uri serves x5c-bearing RSA keys.
- If keys were recently rotated, clear any cached OpenID configuration and re-fetch the JWKS.
- If you control the JWKS source (test fixture/custom IdP), add x5c certificate values to each RSA key entry.
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
$jwks = json_decode(file_get_contents($jwksUri), true);
$usable = array_filter($jwks['keys'] ?? [], fn($k) => isset($k['x5c']) && is_array($k['x5c']) && $k['x5c'] !== []);
if ($usable === []) {
throw new RuntimeException('JWKS contains no x5c-bearing keys; JWT verification will fail');
} Type guard
function jwksHasVerifiableKeys(array $keys): bool {
foreach ($keys as $key) {
if (isset($key['x5c']) && is_array($key['x5c']) && $key['x5c'] !== []) {
return true;
}
}
return false;
} Try / catch
try {
$keys = $provider->getJwtVerificationKeys();
} catch (InternalErrorException $e) {
if ($e->getMessage() === 'No JWT key defined for Azure service.') {
Log::error('JWKS yielded zero usable keys — check x5c presence and tenant configuration');
}
throw $e;
} Prevention
- Verify the discovery document targets the correct Azure AD tenant so jwks_uri serves x5c RSA keys
- Periodically fetch and validate the JWKS (non-empty keys with x5c) as a health check
- Clear cached OpenID configuration after Azure key rotations
- Ensure custom/mock JWKS fixtures include x5c arrays for every key
When it happens
Trigger: The JWKS response contains key entries without an 'x5c' member (or with a non-array x5c), or 'keys' is an empty array — the code silently skips entries without x5c and only fails at the end with this message.
Common situations: Azure AD rotating keys or serving EC-only keys without x5c in a non-standard endpoint; a custom/alternative JWKS source (e.g. a different IdP routed through this provider) whose keys lack x5c; mock fixtures missing x5c; Azure outage returning a minimal key set.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Invalid JWKS endpoint response. Keys missing.
- Cannot parse JWKS endpoint response.
- Failed to public key properties from certificate
- Failed to read certificate
- Failed to read public key from certificate
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/a0302d4280dbf77d.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Sso/src/Utility/Azure/Provider/AzureProvider.php:230
throw new InternalErrorException($msg);
}
$pkey_array = openssl_pkey_get_details($pkey_object);
if ($pkey_array === false) {
$msg = __('Failed to public key properties from certificate: {0}', $encodedkey);
throw new InternalErrorException($msg);
}
$publicKey = $pkey_array['key'];
$keys[$keyinfo['kid']] = new Key($publicKey, 'RS256');
}
}
}
if (empty($keys)) {
throw new InternalErrorException('No JWT key defined for Azure service.');
}
return $keys;
}
}
View on GitHub (pinned to 31c1bbc10f)