Removing a master-eligible node from an Elasticsearch cluster can break quorum and stall cluster-state updates if the remaining voters cannot form a majority. Voting configuration exclusions provide a controlled drain mechanism so a selected node is removed from elections before shutdown or decommissioning.

Cluster coordination stores the active voting configuration in cluster metadata and uses it to elect a master and commit cluster-state changes. The /_cluster/voting_config_exclusions API records excluded nodes (by name or ID) so the voting set can be safely reconfigured without those nodes participating.

Exclusions are intended for master-eligible nodes only; excluding data-only nodes is unnecessary. A majority of master-eligible nodes must remain available (for example, at least 2 of 3) and exclusions should be cleared after node removal to restore normal elections and avoid reaching cluster.max_voting_config_exclusions. Security-enabled clusters require authenticated requests and TLS parameters (for example, -u credentials and --cacert).

Steps to set Elasticsearch voting configuration exclusions:

  1. Check the cluster health before excluding a master-eligible node.
    $ curl --silent --show-error "http://localhost:9200/_cluster/health?filter_path=cluster_name,status,number_of_nodes,number_of_data_nodes&pretty"
    {
      "cluster_name" : "search-cluster",
      "status" : "green",
      "number_of_nodes" : 3,
      "number_of_data_nodes" : 3
    }
  2. Identify the master-eligible node name to exclude from the node list.
    $ curl --silent --show-error "http://localhost:9200/_cat/nodes?v"
    ip         heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
    192.0.2.41           26          83   5    4.15    2.12     0.82 cdfhilmrstw *      node-02
    192.0.2.40           65          83   5    4.15    2.12     0.82 cdfhilmrstw -      node-01
    192.0.2.42           60          83   5    4.15    2.12     0.82 cdfhilmrstw -      node-03

    The node.role column contains m for master-eligible nodes, and the master column shows * for the currently elected master.

  3. Check current voting configuration exclusions.
    $ curl --silent --show-error "http://localhost:9200/_cluster/state?filter_path=metadata.cluster_coordination.voting_config_exclusions&pretty"
    {
      "metadata" : {
        "cluster_coordination" : {
          "voting_config_exclusions" : [ ]
        }
      }
    }
  4. Add the node to voting configuration exclusions.
    $ curl -sS -D - -o /dev/null -X POST "http://localhost:9200/_cluster/voting_config_exclusions?node_names=node-03&timeout=1m"
    HTTP/1.1 200 OK
    X-elastic-product: Elasticsearch
    content-type: application/json
    content-length: 0

    Multiple nodes can be excluded by passing a comma-separated list to node_names or by using node_ids.

  5. Confirm the voting exclusion is registered in cluster coordination metadata.
    $ curl --silent --show-error "http://localhost:9200/_cluster/state?filter_path=metadata.cluster_coordination.voting_config_exclusions&pretty"
    {
      "metadata" : {
        "cluster_coordination" : {
          "voting_config_exclusions" : [
            {
              "node_id" : "1DpVn3_RSwS56-6HML0oMg",
              "node_name" : "node-03"
            }
          ]
        }
      }
    }
  6. Stop the Elasticsearch service on the excluded node.
    $ sudo systemctl stop elasticsearch

    Stopping too many master-eligible nodes can cause quorum loss and prevent cluster-state updates, which can make the cluster unavailable.

  7. Confirm the cluster still has an elected master.
    $ curl --silent --show-error "http://localhost:9200/_cat/master?v"
    id                     host       ip         node
    aQOkC_DIRv-a37tZ0MupXA 192.0.2.41 192.0.2.41 node-02
  8. Clear the voting configuration exclusions.
    $ curl -sS -D - -o /dev/null -X DELETE "http://localhost:9200/_cluster/voting_config_exclusions?wait_for_removal=true"
    HTTP/1.1 200 OK
    X-elastic-product: Elasticsearch
    content-type: application/json
    content-length: 0

    Use wait_for_removal=true when decommissioning so the request waits until the excluded node leaves the cluster, or set wait_for_removal=false to clear immediately when the node name is expected to return.

  9. Verify the voting configuration exclusion list is empty.
    $ curl --silent --show-error "http://localhost:9200/_cluster/state?filter_path=metadata.cluster_coordination.voting_config_exclusions&pretty"
    {
      "metadata" : {
        "cluster_coordination" : {
          "voting_config_exclusions" : [ ]
        }
      }
    }