{"record":{"id":"f85863233093e5a0","repo":"elastic/elasticsearch","slug":"node-cannot-be-null","errorCode":null,"errorMessage":"node cannot be null","messagePattern":"node cannot be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"client/rest/src/main/java/org/elasticsearch/client/RestClientBuilder.java","lineNumber":140,"sourceCode":"            + \",t=\"\n            + metaVersion\n            + \",hc=\"\n            + (httpClientVersion == null ? \"\" : httpClientVersion.getRelease())\n            + LanguageRuntimeVersions.getRuntimeMetadata();\n    }\n\n    /**\n     * Creates a new builder instance and sets the hosts that the client will send requests to.\n     *\n     * @throws IllegalArgumentException if {@code nodes} is {@code null} or empty.\n     */\n    RestClientBuilder(List<Node> nodes) {\n        if (nodes == null || nodes.isEmpty()) {\n            throw new IllegalArgumentException(\"nodes must not be null or empty\");\n        }\n        for (Node node : nodes) {\n            if (node == null) {\n                throw new IllegalArgumentException(\"node cannot be null\");\n            }\n        }\n        this.nodes = nodes;\n    }\n\n    /**\n     * Sets the default request headers, which will be sent along with each request.\n     * <p>\n     * Request-time headers will always overwrite any default headers.\n     *\n     * @throws NullPointerException if {@code defaultHeaders} or any header is {@code null}.\n     */\n    public RestClientBuilder setDefaultHeaders(Header[] defaultHeaders) {\n        Objects.requireNonNull(defaultHeaders, \"defaultHeaders must not be null\");\n        for (Header defaultHeader : defaultHeaders) {\n            Objects.requireNonNull(defaultHeader, \"default header must not be null\");\n        }\n        this.defaultHeaders = defaultHeaders;","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/client/rest/src/main/java/org/elasticsearch/client/RestClientBuilder.java#L122-L158","documentation":"Constructor guard on RestClientBuilder: each entry in the nodes list must be non-null. A null slot is rejected because the client would dereference it on every request.","triggerScenarios":"Passing a List<Node> containing a null element, e.g. from a stream/map that produced null for a malformed entry.","commonSituations":"Parsing hosts where a blank line produced null; Collections.nCopies or array conversion slipping in a null; builder used with varargs where one arg was null.","solutions":["Filter nulls out of the host list before constructing the builder.","Fix the producer that yielded null (e.g. skip blank lines when parsing hosts file/env).","Add a unit test asserting the parsed list has no nulls."],"exampleFix":"// before\nList<Node> nodes = lines.stream().map(l -> l.isBlank() ? null : parse(l)).toList();\nnew RestClientBuilder(nodes);\n// after\nList<Node> nodes = lines.stream().filter(l -> !l.isBlank()).map(l -> parse(l)).toList();\nnew RestClientBuilder(nodes);","handlingStrategy":"validation","validationCode":"nodes.removeIf(Objects::isNull);\nif (nodes.isEmpty()) throw new IllegalArgumentException(\"no non-null nodes\");","typeGuard":"nodes.stream().allMatch(Objects::nonNull)","tryCatchPattern":null,"preventionTips":["Filter nulls at the producer side (parser/stream) rather than relying on the builder to catch them.","Add a test that the host-loading routine yields no nulls."],"tags":["rest-client","builder","validation","null-safety"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}