elastic/elasticsearch · error · IllegalArgumentException
sniffAfterFailureDelayMillis must be greater than 0
Error message
sniffAfterFailureDelayMillis must be greater than 0
What it means
SnifferBuilder guard: the delay before a failure-triggered sniff must be strictly positive. Zero or negative would make the post-failure sniff fire instantly (or never), defeating the purpose of a short recovery delay.
Source
Thrown at client/sniffer/src/main/java/org/elasticsearch/client/sniff/SnifferBuilder.java:65
/**
* Sets the interval between consecutive ordinary sniff executions in milliseconds. Will be honoured when
* sniffOnFailure is disabled or when there are no failures between consecutive sniff executions.
* @throws IllegalArgumentException if sniffIntervalMillis is not greater than 0
*/
public SnifferBuilder setSniffIntervalMillis(int sniffIntervalMillis) {
if (sniffIntervalMillis <= 0) {
throw new IllegalArgumentException("sniffIntervalMillis must be greater than 0");
}
this.sniffIntervalMillis = sniffIntervalMillis;
return this;
}
/**
* Sets the delay of a sniff execution scheduled after a failure (in milliseconds)
*/
public SnifferBuilder setSniffAfterFailureDelayMillis(int sniffAfterFailureDelayMillis) {
if (sniffAfterFailureDelayMillis <= 0) {
throw new IllegalArgumentException("sniffAfterFailureDelayMillis must be greater than 0");
}
this.sniffAfterFailureDelayMillis = sniffAfterFailureDelayMillis;
return this;
}
/**
* Sets the {@link NodesSniffer} to be used to read hosts. A default instance of {@link ElasticsearchNodesSniffer}
* is created when not provided. This method can be used to change the configuration of the {@link ElasticsearchNodesSniffer},
* or to provide a different implementation (e.g. in case hosts need to taken from a different source).
*/
public SnifferBuilder setNodesSniffer(NodesSniffer nodesSniffer) {
Objects.requireNonNull(nodesSniffer, "nodesSniffer cannot be null");
this.nodesSniffer = nodesSniffer;
return this;
}
/**
* Creates the {@link Sniffer} based on the provided configuration.View on GitHub (pinned to db6a809a66)
Solutions
- Pass a positive value in milliseconds, e.g. 60000 (1 minute) which matches the default.
- Validate config-derived delays before calling the setter.
- Confirm the unit (milliseconds) and that the source value is non-zero.
Example fix
// before Sniffer.builder(client).setSniffAfterFailureDelayMillis(delaySec).build(); // 0 or wrong unit // after Sniffer.builder(client).setSniffAfterFailureDelayMillis(Math.max(1, delaySec * 1000)).build();
Defensive patterns
Strategy: validation
Validate before calling
if (delayMs <= 0) throw new IllegalArgumentException("sniffAfterFailureDelayMillis must be > 0; got " + delayMs);
Sniffer.builder(client).setSniffAfterFailureDelayMillis(delayMs); Type guard
sniffAfterFailureDelayMillis > 0
Prevention
- Validate config-derived delay before forwarding.
- Mind the milliseconds unit.
When it happens
Trigger: Calling Sniffer.builder(client).setSniffAfterFailureDelayMillis(0) or a value computed to <= 0.
Common situations: Config-driven delay left unset then defaulted to 0; arithmetic that produced a non-positive value; passing seconds instead of milliseconds.
Related errors
- sniffRequestTimeoutMillis must be greater than 0
- sniffIntervalMillis must be greater than 0
- classname is a required setting for esplugin
- classname is a forbidden for stable esplugin
- invalid deploymentTarget '{}', expected one of {}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/04e135c6d8f78eb8.
Report an issue: GitHub.