elastic/elasticsearch · error · IllegalStateException

sniffer was not set, unable to sniff on failure

Error message

sniffer was not set, unable to sniff on failure

What it means

SniffOnFailureListener.onFailure requires a Sniffer to be registered first via setSniffer. If a request fails before setSniffer was called, the listener has nothing to trigger and raises IllegalStateException instead of silently swallowing the event.

Source

Thrown at client/sniffer/src/main/java/org/elasticsearch/client/sniff/SniffOnFailureListener.java:59

    }

    /**
     * Sets the {@link Sniffer} instance used to perform sniffing
     * @throws IllegalStateException if the sniffer was already set, as it can only be set once
     */
    public void setSniffer(Sniffer sniffer) {
        Objects.requireNonNull(sniffer, "sniffer must not be null");
        if (set.compareAndSet(false, true)) {
            this.sniffer = sniffer;
        } else {
            throw new IllegalStateException("sniffer can only be set once");
        }
    }

    @Override
    public void onFailure(Node node) {
        if (sniffer == null) {
            throw new IllegalStateException("sniffer was not set, unable to sniff on failure");
        }
        sniffer.sniffOnFailure();
    }
}

View on GitHub (pinned to db6a809a66)

Solutions

  1. Always call setSniffer immediately after constructing both the RestClient and the Sniffer, before any traffic.
  2. Do not register the listener on the RestClient until its Sniffer is set.
  3. Add a startup assertion that listener.getSniffer() is non-null before issuing requests.

Example fix

// before
SniffOnFailureListener l = new SniffOnFailureListener();
RestClient client = RestClient.builder(host).setFailureListener(l).build();
// forgot: l.setSniffer(Sniffer.builder(client).build());
client.performRequest(req); // a failure throws 'sniffer was not set'
// after
RestClient client = RestClient.builder(host).setFailureListener(l).build();
l.setSniffer(Sniffer.builder(client).build());
client.performRequest(req);
Defensive patterns

Strategy: validation

Validate before calling

RestClient client = RestClient.builder(host).setFailureListener(listener).build();
Sniffer sniffer = Sniffer.builder(client).build();
listener.setSniffer(sniffer); // MUST come before issuing any traffic
assert sniffer != null;

Prevention

When it happens

Trigger: A node failure occurs between constructing the listener and calling setSniffer(sniffer); setSniffer was forgotten entirely in wiring code.

Common situations: Ordering bug: client builder registered the failure listener but the Sniffer was never built/attached; conditional sniffer creation that was skipped but listener remained.

Related errors


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