spring-projects/spring-security · error · JwtDecoderInitializationException

Failed to lazily resolve the supplied JwtDecoder instance

Error message

Failed to lazily resolve the supplied JwtDecoder instance

What it means

SupplierJwtDecoder resolves its JwtDecoder lazily via a Supplier, memoizing the result in a SingletonSupplier. If the supplier throws when first invoked, the exception is wrapped and rethrown as IllegalStateException with message 'Failed to lazily resolve the supplied JwtDecoder instance', preserving the cause. Subsequent decodes retry the supplier since resolution failed.

Solutions

  1. Inspect the cause (getCause()) to find the underlying supplier failure
  2. Verify the jwk-set URI / issuer configuration points at a reachable JWKS endpoint
  3. Ensure the authorization server is running before the resource server decodes tokens
  4. Add retry/backoff: the supplier is re-invoked on the next decode, so a transient outage self-heals

Example fix

// before
new SupplierJwtDecoder(() -> { throw new IllegalArgumentException("bad uri"); })
// after: validate config before constructing
@Bean
JwtDecoder jwtDecoder() {
    return new SupplierJwtDecoder(() -> {
        String uri = env.getRequiredProperty("spring.security.oauth2.resourceserver.jwt.jwk-set-uri");
        return NimbusJwtDecoder.withJwkSetUri(uri).build();
    });
}
Defensive patterns

Strategy: try-catch

Validate before calling

// fail fast at startup instead of lazily
JwtDecoder d = new SupplierJwtDecoder(supplier);
d.decode("eyJhbGciOi..."); // warm up and surface config errors at boot

Try / catch

try {
    Jwt jwt = decoder.decode(token);
} catch (IllegalStateException ex) {
    Throwable cause = ex.getCause(); // real reason: unreachable JWKS, bad issuer, etc.
    log.error("JwtDecoder failed to resolve lazily", cause);
    // retry is safe: the supplier is re-invoked on next decode
}

Prevention

When it happens

Trigger: The supplied JwtDecoder factory fails on first decode call, e.g. a NimbusJwtDecoder built from a JwkSetUri whose JWKS endpoint is unreachable, a misconfigured issuer URI, or a supplier throwing while reading keys.

Common situations: Resource server starting before the authorization server's JWKS endpoint is up, wrong jwk-set URI or network/firewall issues, misconfigured OAuth2 issuer, or a supplier that throws NPE due to missing beans.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/fccda7079cccabec. Report an issue: GitHub.

Appendix: source

Thrown at oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/SupplierJwtDecoder.java:39

import org.springframework.util.function.SingletonSupplier;

/**
 * A {@link JwtDecoder} that lazily initializes another {@link JwtDecoder}.
 *
 * @author Josh Cummings
 * @since 5.6
 */
public final class SupplierJwtDecoder implements JwtDecoder {

	private final Supplier<JwtDecoder> delegate;

	public SupplierJwtDecoder(Supplier<JwtDecoder> jwtDecoderSupplier) {
		this.delegate = SingletonSupplier.of(() -> {
			try {
				return jwtDecoderSupplier.get();
			}
			catch (Exception ex) {
				throw wrapException(ex);
			}
		});
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Jwt decode(String token) throws JwtException {
		return this.delegate.get().decode(token);
	}

	private JwtDecoderInitializationException wrapException(Exception ex) {
		return new JwtDecoderInitializationException("Failed to lazily resolve the supplied JwtDecoder instance", ex);
	}

}

View on GitHub (pinned to 96852e8860)