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 SpringAiOpenAiHttpClient builder treats maxIdleConnections and keepAliveDuration as a pair: both or neither must be set to configure a custom connection pool. Setting only one is an invalid builder state and build() throws IllegalStateException.
Source
Thrown at models/spring-ai-openai/src/main/java/org/springframework/ai/openai/http/okhttp/SpringAiOpenAiHttpClient.java:575
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)).
- Remove both settings to fall back to OkHttp's default connection pool.
- Add a startup self-check that builds the client once and fails fast with a clear message.
Example fix
// before
SpringAiOpenAiHttpClient.builder().maxIdleConnections(10).build();
// after
SpringAiOpenAiHttpClient.builder()
.maxIdleConnections(10)
.keepAliveDuration(Duration.ofMinutes(5))
.build(); Defensive patterns
Strategy: validation
Validate before calling
if ((maxIdleConnections == null) != (keepAliveDuration == null)) {
throw new IllegalStateException("Set both maxIdleConnections and keepAliveDuration, or neither");
} Try / catch
try {
client = SpringAiOpenAiHttpClient.builder()
.maxIdleConnections(cfg.idle())
.keepAliveDuration(cfg.keepAlive())
.build();
} catch (IllegalStateException e) {
throw new ClientConfigurationException("Invalid pool configuration: " + e.getMessage(), e);
} Prevention
- Always set pool options as a pair in config code
- Bind related properties together in your configuration class
- Build the client at startup to fail fast
When it happens
Trigger: Calling SpringAiOpenAiHttpClient.builder().maxIdleConnections(5).build() without keepAliveDuration (or the reverse), then invoking build() at SpringAiOpenAiHttpClient.java:575.
Common situations: Copy-pasted tuning snippets that set only the pool size, config binding that populates one property but not its companion, or migration from a client that accepted a lone pool-size setting.
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/a66f5ce4ed5cc82c.
Report an issue: GitHub.