{"record":{"id":"42582a87633aa888","repo":"elastic/elasticsearch","slug":"sniffer-was-not-set-unable-to-sniff-on-failure","errorCode":null,"errorMessage":"sniffer was not set, unable to sniff on failure","messagePattern":"sniffer was not set, unable to sniff on failure","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"client/sniffer/src/main/java/org/elasticsearch/client/sniff/SniffOnFailureListener.java","lineNumber":59,"sourceCode":"    }\n\n    /**\n     * Sets the {@link Sniffer} instance used to perform sniffing\n     * @throws IllegalStateException if the sniffer was already set, as it can only be set once\n     */\n    public void setSniffer(Sniffer sniffer) {\n        Objects.requireNonNull(sniffer, \"sniffer must not be null\");\n        if (set.compareAndSet(false, true)) {\n            this.sniffer = sniffer;\n        } else {\n            throw new IllegalStateException(\"sniffer can only be set once\");\n        }\n    }\n\n    @Override\n    public void onFailure(Node node) {\n        if (sniffer == null) {\n            throw new IllegalStateException(\"sniffer was not set, unable to sniff on failure\");\n        }\n        sniffer.sniffOnFailure();\n    }\n}\n","sourceCodeStart":41,"sourceCodeEnd":64,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/client/sniffer/src/main/java/org/elasticsearch/client/sniff/SniffOnFailureListener.java#L41-L64","documentation":"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.","triggerScenarios":"A node failure occurs between constructing the listener and calling setSniffer(sniffer); setSniffer was forgotten entirely in wiring code.","commonSituations":"Ordering bug: client builder registered the failure listener but the Sniffer was never built/attached; conditional sniffer creation that was skipped but listener remained.","solutions":["Always call setSniffer immediately after constructing both the RestClient and the Sniffer, before any traffic.","Do not register the listener on the RestClient until its Sniffer is set.","Add a startup assertion that listener.getSniffer() is non-null before issuing requests."],"exampleFix":"// before\nSniffOnFailureListener l = new SniffOnFailureListener();\nRestClient client = RestClient.builder(host).setFailureListener(l).build();\n// forgot: l.setSniffer(Sniffer.builder(client).build());\nclient.performRequest(req); // a failure throws 'sniffer was not set'\n// after\nRestClient client = RestClient.builder(host).setFailureListener(l).build();\nl.setSniffer(Sniffer.builder(client).build());\nclient.performRequest(req);","handlingStrategy":"validation","validationCode":"RestClient client = RestClient.builder(host).setFailureListener(listener).build();\nSniffer sniffer = Sniffer.builder(client).build();\nlistener.setSniffer(sniffer); // MUST come before issuing any traffic\nassert sniffer != null;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Wire listener -> sniffer before any request leaves the process.","Add a startup self-check that the sniffer is attached."],"tags":["sniffer","lifecycle","listener","ordering"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}