spring-projects/spring-ai · error · IllegalStateException
Both or none of `maxIdleConnections` and `keepAliveDuration`
Error message
Both or none of `maxIdleConnections` and `keepAliveDuration` must be set, but only one was set
What it means
The SpringAiAnthropicHttpClient.Builder's build() validates that the OkHttp connection-pool tuning options are set as a pair. If exactly one of maxIdleConnections or keepAliveDuration was provided, it throws IllegalStateException, because a ConnectionPool requires both values and a half-specified pool is a configuration mistake.
Source
Thrown at models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/http/okhttp/SpringAiAnthropicHttpClient.java:637
toHttpResponse(response));
return authed.map(req -> toRequestComputeUrl(req, null)).orElse(null);
});
}
ExecutorService userDispatcherExecutor = this.dispatcherExecutorService;
boolean ownsDispatcherExecutor = userDispatcherExecutor == null;
ExecutorService dispatcherBase = (userDispatcherExecutor != null) ? userDispatcherExecutor
: defaultDispatcherExecutor();
ExecutorService dispatcherExecutor = ContextExecutorService.wrap(dispatcherBase,
ContextSnapshotFactory.builder().build());
okBuilder.dispatcher(new Dispatcher(dispatcherExecutor));
if (this.maxIdleConnections != null && this.keepAliveDuration != null) {
okBuilder.connectionPool(new ConnectionPool(this.maxIdleConnections, this.keepAliveDuration.toNanos(),
TimeUnit.NANOSECONDS));
}
else if ((this.maxIdleConnections == null) != (this.keepAliveDuration == null)) {
throw new IllegalStateException(
"Both or none of `maxIdleConnections` and `keepAliveDuration` must be set, but only one was set");
}
if (this.sslSocketFactory != null && this.trustManager != null) {
okBuilder.sslSocketFactory(this.sslSocketFactory, this.trustManager);
}
else if ((this.sslSocketFactory == null) != (this.trustManager == null)) {
throw new IllegalStateException(
"Both or none of `sslSocketFactory` and `trustManager` must be set, but only one was set");
}
if (this.hostnameVerifier != null) {
okBuilder.hostnameVerifier(this.hostnameVerifier);
}
OkHttpClient okClient = okBuilder.build();
// Same-host traffic: raise per-host limit to overall request limit. Matches
// the SDK's tuning at the bottom of `OkHttpClient.Builder.build()`.View on GitHub (pinned to 98a7beda4f)
Solutions
- Set both values together: .maxIdleConnections(n).keepAliveDuration(Duration.ofMinutes(5)).
- If tuning is not needed, remove both settings and use OkHttp's default pool.
- Review your configuration binding so that the two properties are always applied as a unit (e.g. a single ConnectionPool config object).
Example fix
// before
SpringAiAnthropicHttpClient.newBuilder().maxIdleConnections(5).build(); // throws
// after
SpringAiAnthropicHttpClient.newBuilder()
.maxIdleConnections(5)
.keepAliveDuration(Duration.ofMinutes(5))
.build(); Defensive patterns
Strategy: validation
Validate before calling
static void checkPoolConfig(Integer maxIdle, Duration keepAlive) {
if ((maxIdle == null) != (keepAlive == null)) {
throw new IllegalStateException("maxIdleConnections and keepAliveDuration must both be set or both null");
}
} Try / catch
try {
return SpringAiAnthropicHttpClient.newBuilder()...build();
} catch (IllegalStateException e) {
if (e.getMessage().contains("maxIdleConnections")) {
// fall back to defaults or apply both settings
}
throw e;
} Prevention
- Encapsulate pool tuning in one config object so the pair is always set together.
- Never conditionally set only one of the two pool options.
- Add a startup-time config validation test for your client builder.
When it happens
Trigger: Building the client with only maxIdleConnections set, or only keepAliveDuration set, e.g. clientBuilder().maxIdleConnections(5).build().
Common situations: Copying a tuning snippet from docs and setting one field; conditional configuration code that sets one property but not the other; refactoring that dropped one of the two builder calls.
Related errors
- Both or none of `maxIdleConnections` and `keepAliveDuration`
- MessageEndpoint must be set
- DataSource must be set (either via dataSource() or jdbcTempl
- Both or none of `sslSocketFactory` and `trustManager` must b
- Both or none of `sslSocketFactory` and `trustManager` must b
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/da1683f054ee79d8.
Report an issue: GitHub.