apache/druid · error · IllegalArgumentException
socketTimeout [ ] must be greater than watchSeconds [ ]
Error message
socketTimeout [%s] must be greater than watchSeconds [%s]
What it means
Cross-field config validation: a blocking Consul watch waits up to watchSeconds; if connection.socketTimeout <= watchSeconds the HTTP read times out before the server responds, so the combination is rejected when the config is constructed.
Solutions
- Raise connection.socketTimeout above watch.watchSeconds (e.g. watchSeconds plus a margin).
- Or lower watchSeconds to fit under the configured socket timeout.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at extensions-contrib/consul-extensions/src/main/java/org/apache/druid/consul/discovery/ConsulDiscoveryConfig.java:122 when the library encounters an invalid state.
Common situations: See trigger scenarios.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/9e9c1dc8c981e982.
Report an issue: GitHub.
Appendix: source
Thrown at extensions-contrib/consul-extensions/src/main/java/org/apache/druid/consul/discovery/ConsulDiscoveryConfig.java:122
ServiceConfig service,
LeaderElectionConfig leader,
WatchConfig watch
)
{
this.connection = connection == null ? new ConnectionConfig(null, null, null, null, null, null, null) : connection;
this.auth = auth == null ? new AuthConfig(null, null, null, null) : auth;
this.service = service;
this.leader = leader;
this.watch = watch == null ? new WatchConfig(null, null, null, null) : watch;
validateCrossFieldConstraints();
}
private void validateCrossFieldConstraints()
{
// Socket timeout must exceed watch timeout to avoid premature disconnects
if (connection.getSocketTimeout().compareTo(watch.getWatchSeconds()) <= 0) {
throw new IAE(
StringUtils.format(
"socketTimeout [%s] must be greater than watchSeconds [%s]",
connection.getSocketTimeout(),
watch.getWatchSeconds()
)
);
}
long serviceTtlSeconds = Math.max(30, service.getHealthCheckInterval().getStandardSeconds() * 3);
if (service.getDeregisterAfter().getStandardSeconds() < serviceTtlSeconds) {
throw new IAE(
StringUtils.format(
"deregisterAfter (%ds) must be >= service TTL (%ds = 3 × healthCheckInterval)",
service.getDeregisterAfter().getStandardSeconds(),
serviceTtlSeconds
)
);
}View on GitHub (pinned to 9b90983fd2)