elastic/elasticsearch · error · IllegalArgumentException

sniffIntervalMillis must be greater than 0

Error message

sniffIntervalMillis must be greater than 0

What it means

SnifferBuilder guard: the periodic sniff interval (milliseconds between scheduled ordinary sniffs) must be strictly positive. Zero or negative would mean never sniffing or scheduling infinitely tight loops, so the builder rejects it.

Source

Thrown at client/sniffer/src/main/java/org/elasticsearch/client/sniff/SnifferBuilder.java:54

    private long sniffAfterFailureDelayMillis = DEFAULT_SNIFF_AFTER_FAILURE_DELAY;
    private NodesSniffer nodesSniffer;

    /**
     * Creates a new builder instance by providing the {@link RestClient} that will be used to communicate with elasticsearch
     */
    SnifferBuilder(RestClient restClient) {
        Objects.requireNonNull(restClient, "restClient cannot be null");
        this.restClient = restClient;
    }

    /**
     * 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}

View on GitHub (pinned to db6a809a66)

Solutions

  1. Pass a positive value in milliseconds, e.g. 300000 (5 minutes) which is near the default.
  2. Validate config-derived intervals before calling the setter.
  3. Double-check the unit: this API is milliseconds, not seconds.

Example fix

// before
Sniffer.builder(client).setSniffIntervalMillis(intervalSeconds).build(); // wrong unit / 0
// after
Sniffer.builder(client).setSniffIntervalMillis(Math.max(1, intervalSeconds * 1000)).build();
Defensive patterns

Strategy: validation

Validate before calling

if (intervalMs <= 0) throw new IllegalArgumentException("sniffIntervalMillis must be > 0; got " + intervalMs);
Sniffer.builder(client).setSniffIntervalMillis(intervalMs);

Type guard

sniffIntervalMillis > 0

Prevention

When it happens

Trigger: Calling Sniffer.builder(client).setSniffIntervalMillis(0) or with a value computed from config that resolved to <= 0.

Common situations: Default-overriding config that left the interval unset then passed 0; arithmetic that produced 0 or negative; misreading the unit (passing seconds instead of ms).

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/07aa1f7144a2331b. Report an issue: GitHub.