quarkusio/quarkus · error · io.quarkus.runtime.configuration.ConfigurationException
Token decryption key for tenant %s can not be read from %s
Error message
Token decryption key for tenant %s can not be read from %s
What it means
TenantConfigContextImpl.createTokenDecryptionKey throws ConfigurationException when the token decryption key file configured via quarkus.oidc.<tenant>.token.decryption-key-location cannot be read. Reading is delegated to OidcUtils.readDecryptionKey and any failure (missing file, malformed PEM) is wrapped with the tenant id and location.
Source
Thrown at extensions/oidc/runtime/src/main/java/io/quarkus/oidc/runtime/TenantConfigContextImpl.java:110
@Override
public Map<Redirect.Location, List<OidcRedirectFilter>> getLocationToRedirectFilters() {
return redirectFilters;
}
private static boolean providerIsNoNull(OidcProvider provider) {
return provider != null && provider.client != null;
}
private static Key createTokenDecryptionKey(OidcProvider provider, String clientSecret) {
Key key = null;
OidcTenantConfig oidcConfig = provider.oidcConfig;
if (oidcConfig.token().decryptionKeyLocation().isPresent()) {
try {
return OidcUtils.readDecryptionKey(oidcConfig.token().decryptionKeyLocation().get());
} catch (Exception ex) {
throw new ConfigurationException(
String.format("Token decryption key for tenant %s can not be read from %s",
oidcConfig.tenantId().get(), oidcConfig.token().decryptionKeyLocation().get()),
ex);
}
}
if (oidcConfig.token().decryptIdToken().orElse(false) || oidcConfig.token().decryptAccessToken()) {
if (provider.client.getClientJwtKey() != null) {
key = provider.client.getClientJwtKey();
} else if (clientSecret != null) {
key = OidcUtils.createSecretKeyFromDigest(clientSecret);
}
}
return key;
}
private static SecretKey createStateSecretKey(OidcTenantConfig config, String possiblePkceSecret) {
if (config.authentication().pkceRequired().orElse(false) || config.authentication().nonceRequired()) {View on GitHub (pinned to e1c734241f)
Solutions
- Fix quarkus.oidc.<tenant>.token.decryption-key-location to point to an existing readable PEM private key file
- Verify the file is mounted/available in the runtime environment (container volume, k8s secret path)
- Re-export the key in valid PEM (PKCS#8) format if the format is wrong
Example fix
// before quarkus.oidc.tenant-b.token.decryption-key-location=/wrong/path/key.pem // after quarkus.oidc.tenant-b.token.decryption-key-location=/deployments/keys/tenant-b-key.pem
Defensive patterns
Strategy: validation
Validate before calling
Path keyPath = Path.of(config.decryptionKeyLocation());
if (!Files.isReadable(keyPath)) throw new IllegalStateException("Decryption key unreadable: " + keyPath); Try / catch
try { startApplication(); } catch (ConfigurationException e) { log.error("Fix token.decryption-key-location: " + e.getMessage(), e.getCause()); } Prevention
- Verify key file paths inside the actual runtime image/container
- Mount keys as read-only volumes with correct permissions
- Validate keys are PEM (PKCS#8) format at deploy time
When it happens
Trigger: Building the tenant's ready context (createReady/tokenDecryptionKey) with oidcConfig.token().decryptionKeyLocation() present; OidcUtils.readDecryptionKey throws (file not found, unreadable, invalid PEM) and the exception is wrapped in ConfigurationException.
Common situations: Wrong path to the private key PEM; key mounted in a container at a different path; file permissions blocking read; key in DER/PKCS12 format not accepted as PEM.
Related errors
- Auth config file not found: ${path}
- Specified Dockerfile: '%s' does not exist.
- Application 'web-app' type is only supported if access token
- Failed to parse the realm name.
- Failed to find a matching OidcTenantConfig for tenant:
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/692a88a7dbf87e2f.
Report an issue: GitHub.