apereo/cas · error

No valid JSON web keys used for encryption can be found

Error message

No valid JSON web keys used for encryption can be found

What it means

This warning is logged by OidcJsonWebKeyStoreUtils.fetchJsonWebKeySetForEncryption when a JWKS entry exists in the encryption keystore cache, but every contained key fails the key.getKey() != null filter — i.e. the JsonWebKey entries carry no usable Key material. The method returns Optional.empty() so no encryption key set is produced.

Solutions

  1. Validate the JWKS JSON contains complete key parameters for each key type (n+e for RSA, x+y+crv for EC, k for oct) and fix or regenerate it
  2. Use jose4j or a JWKS validator to parse the JWKS and confirm each key yields non-null getKey() before publishing it
  3. Re-export the keys from the original keystore (e.g. JWK from KeyStore conversion) instead of hand-authoring the JSON
  4. If the cached entry is stale/broken, invalidate the registered-service JWKS cache and reload from a corrected source

Example fix

// before: incomplete RSA enc key in JWKS
{"keys":[{"kty":"RSA","use":"enc","kid":"rp-enc-1"}]}
// after: include full public key material
{"keys":[{"kty":"RSA","use":"enc","kid":"rp-enc-1","n":"0vx7...","e":"AQAB"}]}
Defensive patterns

Strategy: validation

Validate before calling

// Validate the JWKS fully parses into keys with real key material
JsonWebKeySet jwks = new JsonWebKeySet(jwksJson);
List<JsonWebKey> usable = jwks.getJsonWebKeys().stream()
    .filter(k -> k.getKey() != null).toList();
if (usable.isEmpty()) {
    throw new IllegalStateException("JWKS parses but no keys carry key material "
        + "(check n/e for RSA, x/y/crv for EC, k for oct)");
}

Type guard

static boolean allKeysHaveMaterial(JsonWebKeySet jwks) {
    return !jwks.getJsonWebKeys().isEmpty()
        && jwks.getJsonWebKeys().stream().allMatch(k -> k.getKey() != null);
}

Try / catch

try {
    Optional<JsonWebKeySet> keys =
        OidcJsonWebKeyStoreUtils.fetchJsonWebKeySetForEncryption(service, cipherExecutor);
    if (keys.isEmpty()) {
        LOG.warn("Cached enc JWKS has no usable key material for {}", service.getClientId());
    }
} catch (Exception e) {
    LOG.error("Failed to build encryption key set", e);
}

Prevention

When it happens

Trigger: Calling fetchJsonWebKeySetForEncryption with a cached JsonWebKeySet whose parsed keys are PublicJsonWebKey instances without a resolvable java.security.Key (e.g. JWKS JSON missing required parameters like 'n'/'e' for RSA or 'x'/'y' for EC, or oct keys missing 'k'), so jose4j constructs JWKs with null Key objects.

Common situations: Hand-edited or truncated JWKS files published by the relying party; JWKS JSON that parses as valid JSON but with malformed/missing key parameters; keys serialized without key material (public-only placeholders); encoding errors in base64url parameters.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/f2b339238a88f6e7. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/jwks/OidcJsonWebKeyStoreUtils.java:285

     * @param cipherExecutor    the cipher executor
     * @return the optional
     */
    public static Optional<JsonWebKeySet> fetchJsonWebKeySetForEncryption(final RegisteredService registeredService,
                                                                          final OidcRegisteredServiceJwtCipherExecutor cipherExecutor) {
        val oidcRegisteredService = (OidcRegisteredService) registeredService;
        val jwks = Objects.requireNonNull(cipherExecutor.getRegisteredServiceJsonWebKeystoreCache().get(
            new OidcJsonWebKeyCacheKey(oidcRegisteredService, OidcJsonWebKeyUsage.ENCRYPTION)));
        if (jwks.isEmpty()) {
            LOGGER.warn("Service [{}] with client id [{}] is configured to encrypt tokens, yet no JSON web key is available",
                oidcRegisteredService.getServiceId(), oidcRegisteredService.getClientId());
            return Optional.empty();
        }
        val jsonWebKey = jwks.get();
        LOGGER.debug("Found JSON web key to encrypt the token: [{}]", jsonWebKey);

        val keys = jsonWebKey.getJsonWebKeys().stream().filter(key -> key.getKey() != null).toList();
        if (keys.isEmpty()) {
            LOGGER.warn("No valid JSON web keys used for encryption can be found");
            return Optional.empty();
        }
        return Optional.of(new JsonWebKeySet(keys));
    }
}

View on GitHub (pinned to e7288fc434)