Configuring JWT Validation Timeouts in Spring Boot 4.0+
Fix connection timeout errors when validating Scalekit JWT tokens in Spring Boot 4.0.0 and later versions.
If you’re using Spring Boot 4.0.0 or later and experiencing connection timeout errors when validating JWT tokens from Scalekit, you’ll need to explicitly configure timeout values. This is a known issue affecting Spring Security’s OAuth2 resource server configuration.
The problem
Section titled “The problem”Your Spring Boot application successfully configures the issuer-uri for JWT validation:
spring: security: oauth2: resourceserver: jwt: issuer-uri: https://auth.scalekit.comBut authentication fails with timeout errors like:
java.net.SocketTimeoutException: Connect timed out at org.springframework.security.oauth2.jwt.JwtDecoders.fromIssuerLocationWhy this happens
Section titled “Why this happens”Starting with Spring Boot 4.0.0, Spring Security changed how it handles HTTP connections during JWT validation:
- Before 4.0.0: Spring used default system timeouts (often much longer)
- After 4.0.0: Spring enforces strict, short timeout defaults that can be too aggressive for production
When your application starts or validates its first JWT token, Spring Security:
- Fetches the OpenID Connect discovery document from
issuer-uri - Retrieves the JWKS (JSON Web Key Set) to verify token signatures
- Caches these for future validations
If these initial requests timeout, authentication fails completely.
Who needs this fix
Section titled “Who needs this fix”This issue specifically affects:
- ✅ Spring Boot applications version 4.0.0 or later
- ✅ Using
issuer-urifor JWT validation (not manualjwk-set-uri) - ✅ Production environments with network latency or firewall rules
- ✅ Applications experiencing intermittent authentication failures
You don’t need this if:
- ❌ Using Spring Boot 3.x or earlier
- ❌ Manually configuring
jwk-set-uriinstead ofissuer-uri - ❌ Already have custom
RestTemplateorWebClientconfigurations
The solution
Section titled “The solution”Configure explicit timeout values for the OAuth2 resource server’s HTTP client. Spring Security provides configuration properties specifically for this:
spring: security: oauth2: resourceserver: jwt: issuer-uri: https://auth.scalekit.com # Configure timeouts for JWKS and discovery endpoints client: registration: connect-timeout: 10000 # 10 seconds for connection read-timeout: 10000 # 10 seconds for reading responsespring.security.oauth2.resourceserver.jwt.issuer-uri=https://auth.scalekit.com# Configure timeouts for JWKS and discovery endpointsspring.security.oauth2.resourceserver.jwt.client.registration.connect-timeout=10000spring.security.oauth2.resourceserver.jwt.client.registration.read-timeout=10000Timeout values explained
Section titled “Timeout values explained”- connect-timeout: Maximum time (in milliseconds) to establish a connection to Scalekit’s servers
- read-timeout: Maximum time (in milliseconds) to wait for a response after connection is established
Recommended values:
- Development: 5000ms (5 seconds) for faster feedback
- Production: 10000-15000ms (10-15 seconds) to handle network variability
Alternative: Programmatic configuration
Section titled “Alternative: Programmatic configuration”If you need more control or want to configure this per-environment, use Java configuration:
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.http.client.SimpleClientHttpRequestFactory;import org.springframework.security.oauth2.jwt.JwtDecoder;import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;import org.springframework.web.client.RestTemplate;
@Configurationpublic class SecurityConfig {
@Bean public JwtDecoder jwtDecoder() { // Create a RestTemplate with custom timeouts SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(10000); // 10 seconds factory.setReadTimeout(10000); // 10 seconds
RestTemplate restTemplate = new RestTemplate(factory);
// Use the custom RestTemplate for JWT validation return NimbusJwtDecoder .withIssuerLocation("https://auth.scalekit.com") .restOperations(restTemplate) .build(); }}This approach gives you:
- Full control over HTTP client configuration
- Ability to add custom headers or interceptors
- Environment-specific timeout tuning
Verifying the fix
Section titled “Verifying the fix”After applying the configuration:
- Restart your application - Spring Security initializes the JWT decoder on startup
- Test authentication - Make a request with a valid Scalekit JWT token
- Check logs - You should see successful JWKS retrieval:
DEBUG o.s.security.oauth2.jwt.JwtDecoder - Retrieved JWKS from https://auth.scalekit.com/.well-known/jwks.jsonIf you still see timeout errors:
- Verify network connectivity to
auth.scalekit.com - Check firewall rules allowing outbound HTTPS
- Increase timeout values if your network has high latency
When to use standard Spring Security instead
Section titled “When to use standard Spring Security instead”This cookbook addresses a specific Spring Boot 4.0+ timeout issue. For general JWT validation setup:
- Follow the Spring Security OAuth2 Resource Server documentation
- Use Scalekit’s standard Java SDK for token validation if not using Spring Security
- Consider the default
issuer-uriconfiguration if you’re not experiencing timeouts