> **Building with AI coding agents?** If you're using an AI coding agent, install the official Scalekit plugin. It gives your agent full awareness of the Scalekit API — reducing hallucinations and enabling faster, more accurate code generation.
>
> - **Claude Code**: `/plugin marketplace add scalekit-inc/claude-code-authstack` then `/plugin install <auth-type>@scalekit-auth-stack`
> - **GitHub Copilot CLI**: `copilot plugin marketplace add scalekit-inc/github-copilot-authstack` then `copilot plugin install <auth-type>@scalekit-auth-stack`
> - **Codex**: run the bash installer, restart, then open Plugin Directory and enable `<auth-type>`
> - **Skills CLI** (Windsurf, Cline, 40+ agents): `npx skills add scalekit-inc/skills --list` then `--skill <skill-name>`
>
> `<auth-type>` / `<skill-name>`: `agentkit`, `full-stack-auth`, `mcp-auth`, `modular-sso`, `modular-scim` — [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# 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

Your Spring Boot application successfully configures the `issuer-uri` for JWT validation:

```yaml
spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://auth.scalekit.com
```

But authentication fails with timeout errors like:

```
java.net.SocketTimeoutException: Connect timed out
  at org.springframework.security.oauth2.jwt.JwtDecoders.fromIssuerLocation
```

## 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:

1. Fetches the OpenID Connect discovery document from `issuer-uri`
2. Retrieves the JWKS (JSON Web Key Set) to verify token signatures
3. Caches these for future validations

If these initial requests timeout, authentication fails completely.

## Who needs this fix

This issue specifically affects:

- ✅ Spring Boot applications version **4.0.0 or later**
- ✅ Using `issuer-uri` for JWT validation (not manual `jwk-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-uri` instead of `issuer-uri`
- ❌ Already have custom `RestTemplate` or `WebClient` configurations

## The solution

For Spring Security servlet resource servers, there are no properties to configure JWT discovery/JWKS HTTP timeouts. Use a custom `JwtDecoder` bean with `RestOperations` (for example, `RestTemplate`) and explicit timeout values:

```java

@Configuration
public 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 gives you:
- Full control over HTTP client configuration
- Ability to add custom headers or interceptors
- Environment-specific timeout tuning (development: 5000ms, production: 10000–15000ms)

## Verifying the fix

After applying the configuration:

1. **Restart your application** - Spring Security initializes the JWT decoder on startup
2. **Test authentication** - Make a request with a valid Scalekit JWT token
3. **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.json
```

If 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

This cookbook addresses a specific Spring Boot 4.0+ timeout issue. For general JWT validation setup:

- Follow the [Spring Security OAuth2 Resource Server documentation](https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/jwt.html)
- Use Scalekit's standard Java SDK for token validation if not using Spring Security
- Consider the default `issuer-uri` configuration if you're not experiencing timeouts

## Related resources

- [Spring Security OAuth2 Resource Server - JWT Timeouts](https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server/jwt.html#oauth2resourceserver-jwt-timeouts)
- [Scalekit API reference](/apis/#tag/authentication)
- [Spring Boot 4.0 Release Notes](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Release-Notes)


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
