Configuring discovery.seed_hosts gives each Elasticsearch node a reliable set of peers to contact during startup, which keeps a multi-node cluster discoverable after restarts, maintenance windows, and network changes.
Cluster discovery happens over the transport layer rather than the HTTP API. The discovery.seed_hosts setting supplies host names or IP addresses for the master-eligible nodes that a joining or restarting node should contact first, and Elasticsearch resolves every address returned for those names before attempting cluster formation.
Current self-managed installs often secure the HTTP layer with HTTPS and authentication, but peer discovery still depends on transport reachability and matching cluster identity. In a multi-node cluster, update the seed host list on every node, including the first installed node, and remove cluster.initial_master_nodes after the cluster forms so later restarts do not trip discovery bootstrap checks.
$ sudo nano /etc/elasticsearch/elasticsearch.yml
Nodes with different cluster.name values never join the same cluster.
cluster.name: search-cluster
discovery.seed_hosts: - es-master-a:9300 - es-master-b:9300 - es-master-c:9300
Use fixed DNS names or IP addresses that resolve to reachable transport endpoints. Each address may be host or host:port; if the port is omitted, Elasticsearch checks transport.profiles.default.port, then transport.port, and otherwise falls back to 9300.
cluster.initial_master_nodes: - es-master-a - es-master-b - es-master-c
cluster.initial_master_nodes is only for the first bootstrap of a brand-new cluster. Do not leave it on nodes joining an existing cluster or on nodes that are restarting.
The first installed node in a multi-node package deployment also needs a complete discovery.seed_hosts list, or later restarts can fail discovery bootstrap checks.
$ sudo systemctl restart elasticsearch
Restart nodes one at a time on an existing cluster so the cluster keeps quorum and shard movement stays controlled.
$ systemctl is-active elasticsearch active
Use sudo journalctl --unit=elasticsearch.service --no-pager --lines=80 when the unit does not return active.
$ curl -sS "http://localhost:9200/_cluster/health?wait_for_nodes=>=3&timeout=60s&filter_path=cluster_name,status,timed_out,number_of_nodes&pretty"
{
"cluster_name" : "search-cluster",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 3
}
number_of_nodes and timed_out confirm discovery more directly than the health color alone.
Recent self-managed package installs typically use https://localhost:9200// with a trusted CA and authentication, for example curl -u elastic "https://localhost:9200/..." or an API key header.</WRAP> - List cluster nodes and confirm that the node rejoined the expected cluster state. <code>$ curl -sS “http://localhost:9200/_cat/nodes?v&s=name&h=ip,name,node.role,master” ip name node.role master 192.0.2.40 es-master-a cdfhilmrstw * 192.0.2.41 es-master-b cdfhilmrstw - 192.0.2.42 es-master-c cdfhilmrstw -</code>
The master column must show exactly one *. If the node is missing from the list, recheck transport reachability, DNS resolution, cluster.name, and whether the seed list targets master-eligible nodes.