Elasticsearch transport.publish_host Setting

transport.publish_host is the address an Elasticsearch node publishes to peers as the contact point for its transport layer. Peers store the published address and use it for all subsequent communication. The setting matters whenever the bind address (transport.host) differs from the address other nodes should use to reach the node - the canonical example being a container with one internal IP and a different external IP, or any host behind NAT.

  • Default: Auto-detected from the bind address. Works for simple flat networks
  • Scope: Per-node, static - requires a restart
  • Possible values: IP address, hostname, or special value like _site_

How transport.publish_host Works

At startup, each node selects a publish address using this priority:

  1. transport.publish_host if set
  2. transport.host if set and unambiguous
  3. The first non-loopback bind address

The selected address is broadcast to every peer the node joins. From that point, peers use that address - not the bind address - to open new connections. Discovery, cluster state updates, and shard requests all flow over the published address.

When the bind address is reachable internally (e.g. inside a Docker network) but a different address is needed externally, peers must be told the externally-reachable address. That's transport.publish_host.

Configuring transport.publish_host

In elasticsearch.yml:

transport.host: 0.0.0.0          # Bind to all interfaces inside the container
transport.publish_host: 10.0.5.12  # Advertise the host-routable address

Verify:

GET /_nodes/_local?filter_path=**.transport.publish_address

In Docker Compose, the typical pattern uses an environment variable mapped to the host IP:

environment:
  - network.host=0.0.0.0
  - transport.publish_host=${HOST_IP}

In Kubernetes, ECK handles publish_host automatically via the pod IP. Custom manifests should set transport.publish_host from the downward API.

When You Need transport.publish_host

Environment Likely need
Bare-metal flat network No - auto-detect works
Cloud VM, single NIC, public IP routed to a private IP Possibly - depends on whether nodes use public or private IPs
Docker host networking No - bind and publish are the same
Docker bridge networking Yes - container IP differs from host-reachable IP
Kubernetes with ECK No - ECK configures this
Kubernetes with custom StatefulSet Yes - usually pod IP from downward API
Behind NAT Yes - publish the NAT'd address peers can reach

Common Pitfalls

  1. Publishing 127.0.0.1 or localhost in a multi-node cluster. Other nodes get the loopback address and can't reach the node.
  2. Publishing a hostname that doesn't resolve consistently across nodes. Some peers see one IP, others see another, leading to flapping discovery.
  3. Forgetting to update transport.publish_host after migrating a node to a new network. Peers continue trying to reach the old address.
  4. Using the auto-detected address on hosts with multiple NICs. Auto-detection picks the first non-loopback address, which may be the wrong network.

Operational Notes

Inspect what each node is publishing:

GET /_cat/nodes?v&h=name,host,transport.address,transport.bind,transport.publish

Pulse tracks publish addresses across cluster restarts and alerts when a node starts publishing an unexpected address - a common cause of partial cluster splits where some peers can reach the node and others can't. The publish-vs-bind mismatch is one of the more time-consuming networking issues to debug manually; surfacing it directly saves an hour of log archaeology.

Frequently Asked Questions

Q: What does transport.publish_host do in Elasticsearch?
A: transport.publish_host is the address a node advertises to peers as its transport contact point. Peers then use that address to open connections. It's necessary when the bind address differs from the address peers can reach, like in containers or behind NAT.

Q: What's the difference between transport.host and transport.publish_host?
A: transport.host is the address the node binds to for incoming transport connections. transport.publish_host is the address advertised to peers as the connect-back point. They're often the same; they differ in NAT and container environments.

Q: Do I need to set transport.publish_host in Docker?
A: Only with bridge networking, where the container's bind address (an internal Docker network IP) differs from the host-routable IP peers should use. With host networking they're the same and the setting is unnecessary.

Q: Can I use a hostname for transport.publish_host?
A: Yes - any value that resolves to a reachable IP works. The risk is inconsistent DNS resolution across nodes, which causes flapping discovery. Static IPs are more reliable.

Q: What happens if transport.publish_host points to an unreachable address?
A: The node joins the cluster but peers can't open new connections to it. Existing connections survive until they break, then the cluster sees the node as disconnected and shards reallocate. Usually surfaces as flapping yellow/red cluster state.

Q: Is transport.publish_host required in Kubernetes?
A: Not when using the ECK operator - it sets publish_host automatically. With a custom StatefulSet or manifest, set publish_host to the pod IP from the Kubernetes downward API.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.