quarkusio/quarkus · error · ConfigurationException

Key is null

Error message

Key is null

What it means

After loading JWT credentials, the resolved Key object was still null — the configured key store did not yield a key (e.g. no alias match or empty key reference) yet no exception was thrown during loading. Quarkus treats a null key as a configuration error.

Source

Thrown at extensions/oidc-common/runtime/src/main/java/io/quarkus/oidc/common/runtime/OidcCommonUtils.java:542

                    if (creds.jwt().keyStorePassword().isPresent()) {
                        ks.load(is, creds.jwt().keyStorePassword().get().toCharArray());
                    } else {
                        ks.load(is, null);
                    }

                    if (creds.jwt().keyPassword().isPresent()) {
                        key = ks.getKey(creds.jwt().keyId().get(), creds.jwt().keyPassword().get().toCharArray());
                    } else {
                        throw new ConfigurationException(
                                "When using a key store, the `quarkus.oidc-client.credentials.jwt.key-password` property must be set");
                    }
                }
            } catch (Exception ex) {
                throw new ConfigurationException("Key can not be loaded", ex);
            }
            if (key == null) {
                throw new ConfigurationException("Key is null");
            }
            return Uni.createFrom().item(key);
        }
    }

    public static String signJwtWithKey(OidcClientCommonConfig oidcConfig, String tokenRequestUri, Key key) {
        // 'jti' and 'iat' claims are created by default, 'iat' - is set to the current time
        JwtSignatureBuilder jwtSignatureBuilder = Jwt
                .claims(additionalClaims(oidcConfig.credentials().jwt().claims()))
                .issuer(oidcConfig.credentials().jwt().issuer().orElse(oidcConfig.clientId().get()))
                .subject(oidcConfig.credentials().jwt().subject().orElse(oidcConfig.clientId().get()))
                .audience(oidcConfig.credentials().jwt().audience().isPresent()
                        ? removeAudienceTrailingSlash(oidcConfig.credentials().jwt(),
                                oidcConfig.credentials().jwt().audience().get())
                        : tokenRequestUri)
                .expiresIn(oidcConfig.credentials().jwt().lifespan()).jws();
        if (oidcConfig.credentials().jwt().tokenKeyId().isPresent()) {
            jwtSignatureBuilder.keyId(oidcConfig.credentials().jwt().tokenKeyId().get());

View on GitHub (pinned to e1c734241f)

Solutions

  1. Set credentials.jwt.key-id (or key alias) to the exact alias of the PrivateKey entry in the key store
  2. Verify with 'keytool -list -keystore keystore.jks' that the alias exists and is a PrivateKeyEntry
  3. Ensure one complete key source is configured: credentials.jwt.key (inline secret), key-file (PEM), or key-store-file + key-password + key-id
  4. Remove stale/empty JWT credential properties that trigger JWT auth without a key

Example fix

// before
quarkus.oidc-client.credentials.jwt.key-store-file=classpath:keystore.jks
quarkus.oidc-client.credentials.jwt.key-id=wrongAlias
// after
quarkus.oidc-client.credentials.jwt.key-store-file=classpath:keystore.jks
quarkus.oidc-client.credentials.jwt.key-id=mySigningKey
quarkus.oidc-client.credentials.jwt.key-password=keypass
Defensive patterns

Strategy: validation

Validate before calling

// pre-check alias resolves to a private key
try (InputStream is = new FileInputStream("keystore.jks")) {
    KeyStore ks = KeyStore.getInstance("JKS");
    ks.load(is, storePassword.toCharArray());
    if (ks.getKey(alias, keyPassword.toCharArray()) == null) {
        throw new IllegalStateException("Alias " + alias + " has no private key");
    }
}

Prevention

When it happens

Trigger: clientJwtKey finishes without exception but 'key' remains null, e.g. the key store entry/alias does not exist, or no key source (key, key-file, key-store-file) actually produced a key while JWT auth was required.

Common situations: key-store-file present but credentials.jwt.key-id (alias) does not match any entry; alias pointing to a certificate entry rather than a private key entry; JWT auth triggered by partial config but the actual key property was mistyped.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/d64895b3e5951d69. Report an issue: GitHub.