Skip to main content
9300

Port 9300Elasticsearch Transport

TCP

Port 9300 is the Elasticsearch inter-node transport port – used for cluster communication between Elasticsearch nodes, master election, shard replication, and cross-cluster search. Clients should always use the REST API on port 9200. Port 9300 uses the Elasticsearch binary transport protocol, not HTTP.

Port Number

9300

Protocol

TCP

Service

Elasticsearch Node-to-Node

Range

IANA Registered (1024–49151)

Description

Elasticsearch's binary transport protocol on port 9300 is used exclusively for cluster-internal communication: node discovery, master election, shard allocation, and data replication. Port 9300 should only be accessible between Elasticsearch cluster nodes – never from application servers or the internet. The Java REST client previously used port 9300 (transport client), but the HTTP REST API on port 9200 is now standard for all clients.

Security risks

  • 1CVE-2015-3253: Elasticsearch remote code execution via Groovy scripting on transport protocol – attacker connecting to 9300 could execute arbitrary code (fixed 1.4.5, 1.5.2)
  • 2Pre-8.0: transport protocol had no TLS or authentication by default – any host reaching 9300 could join the cluster, read all data, and execute as a node
  • 3Node impersonation: without transport TLS, attacker adds a malicious node to the cluster, receives shard replicas, and exfiltrates index data silently
  • 4Split-brain risk: if port 9300 is partially blocked (e.g., asymmetric firewall), nodes lose quorum and elect multiple masters, potentially causing data loss on recovery
  • 5Cross-cluster replication and cross-cluster search (CCS) traverse port 9300 – misconfigured remote clusters allow unauthorized data access across environments

Firewall guidance

Port 9300 must ONLY be accessible between Elasticsearch cluster nodes. Use security groups or iptables to whitelist exact node IPs. Block from all application servers (they use 9200). In Elasticsearch 8.0+, transport TLS is enabled by default (xpack.security.transport.ssl.enabled: true). For pre-8.0 clusters, manually configure transport TLS immediately – this is the highest-priority security hardening.

Diagnosis commands

Show transport addresses of all cluster nodes (verify expected IPs)

shell
curl -s http://localhost:9200/_nodes/transport | jq '.nodes[].transport_address'

Quick cluster health – if nodes < expected, transport connectivity is broken

shell
curl -s http://localhost:9200/_cluster/health | jq '{status, number_of_nodes, active_shards_percent}'

Scan subnet for exposed 9300 ports (should only find cluster peers)

shell
nmap -sV -p 9300 10.0.1.0/24

Verify transport TLS is active between nodes (ES 8.0+)

shell
openssl s_client -connect node2:9300 </dev/null 2>&1 | grep 'Verify return code'

Usage examples

Port 9300 – Elasticsearch Transport
shell
curl http://localhost:9200/_cluster/state
# Node-to-node comms on 9300 are internal – not for application clients
iptables -A INPUT -p tcp --dport 9300 -s 10.0.0.0/8 -j ACCEPT

Common services on this port

ElasticsearchOpenSearchAmazon OpenSearch ServiceElastic Cloud

Related ports

History

Port 9300 was chosen alongside 9200 when Elasticsearch was created in 2010. The transport protocol is a binary format optimized for speed and used for all inter-node communication. Before version 7.0, Java clients used the transport client (port 9300) directly; this was deprecated in favor of the REST client (port 9200). Elasticsearch 8.0 (2022) made transport TLS mandatory by default, closing a decade-long security gap.

FAQ

Why can't I use port 9300 for application clients?

The transport protocol is internal, binary, and version-specific – it changes between minor versions without backward compatibility guarantees. Applications must use the HTTP REST API on port 9200 via the official Elasticsearch client libraries. The old Java TransportClient (which used 9300) was removed in Elasticsearch 8.0.

How do I verify transport TLS is working?

Check elasticsearch.yml: xpack.security.transport.ssl.enabled must be true with valid certificate/key/CA paths. Test: curl -s http://localhost:9200/_nodes?filter_path=**.transport_address,**.transport.publish_address shows the transport addresses. If nodes can communicate, your _cluster/health node_count matches. For explicit TLS check: openssl s_client -connect <peer>:9300.