{"record":{"id":"6555a9d719f1f1f8","repo":"elastic/elasticsearch","slug":"host-cannot-be-null","errorCode":null,"errorMessage":"host cannot be null","messagePattern":"host cannot be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"client/rest/src/main/java/org/elasticsearch/client/Node.java","lineNumber":70,"sourceCode":"    private final String version;\n    /**\n     * Roles that the Elasticsearch process on the host has or {@code null}\n     * if we don't know what roles the node has.\n     */\n    private final Roles roles;\n    /**\n     * Attributes declared on the node.\n     */\n    private final Map<String, List<String>> attributes;\n\n    /**\n     * Create a {@linkplain Node} with metadata. All parameters except\n     * {@code host} are nullable and implementations of {@link NodeSelector}\n     * need to decide what to do in their absence.\n     */\n    public Node(HttpHost host, Set<HttpHost> boundHosts, String name, String version, Roles roles, Map<String, List<String>> attributes) {\n        if (host == null) {\n            throw new IllegalArgumentException(\"host cannot be null\");\n        }\n        this.host = host;\n        this.boundHosts = boundHosts;\n        this.name = name;\n        this.version = version;\n        this.roles = roles;\n        this.attributes = attributes;\n    }\n\n    /**\n     * Create a {@linkplain Node} without any metadata.\n     */\n    public Node(HttpHost host) {\n        this(host, null, null, null, null, null);\n    }\n\n    /**\n     * Contact information for the host.","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/client/rest/src/main/java/org/elasticsearch/client/Node.java#L52-L88","documentation":"The Node constructor that carries metadata requires a non-null HttpHost because every other Node operation (routing, auth cache, connection) keys off host. All other parameters are nullable and left to NodeSelector policy, but host is a structural invariant — a Node without a host cannot exist.","triggerScenarios":"Calling new Node(null, boundHosts, name, version, roles, attributes) — typically because a cluster-info or nodes-info response lacked the host field, or caller code built a Node from a parsed DTO where host was missing.","commonSituations":"Parsing a malformed nodes-info JSON where the host entry is absent; programmatic Node construction from external config with an unset host; refactoring that drops the host assignment.","solutions":["Ensure the HttpHost is resolved and non-null before constructing the Node — validate the source DTO/config.","If the upstream data legitimately lacks a host, skip that node or fix the data producer to include it.","Fail fast at the parsing boundary with a clearer error rather than letting Node throw."],"exampleFix":"// before\nNode n = new Node(parsed.host, parsed.boundHosts, parsed.name, ...); // parsed.host == null\n// after\nObjects.requireNonNull(parsed.host, \"nodes-info entry missing host for node \" + parsed.name);\nNode n = new Node(parsed.host, parsed.boundHosts, parsed.name, ...);","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(host, \"HttpHost must be resolved before building Node\");\nNode n = new Node(host, boundHosts, name, version, roles, attributes);","typeGuard":"static HttpHost requireHost(HttpHost h) {\n    if (h == null) throw new IllegalArgumentException(\"host is required\");\n    return h;\n}","tryCatchPattern":null,"preventionTips":["Validate parsed cluster/node DTOs at the boundary and require host.","Never construct Node from partially-resolved data; wait until host is known.","Fail fast at the parser with a contextual message rather than letting Node reject it."],"tags":["rest-client","validation","preconditions","node"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}