The Elasticsearch ConnectException with "Connection refused" occurs when a client or node attempts to connect to Elasticsearch but the target system actively rejects the connection. This typically happens when Elasticsearch is not running, not listening on the expected address, or when network/firewall rules block the connection.
The ConnectException with "Connection refused" is a network-level error indicating that a TCP connection attempt to Elasticsearch was explicitly rejected by the target system. This differs from connection timeout errors where there's no response at all - connection refused means the operating system on the target machine actively declined the connection. In Elasticsearch contexts, this error commonly occurs when applications, clients, or other nodes try to connect to port 9200 (HTTP) or 9300 (transport protocol) but cannot establish a connection. The connection refusal happens at the OS networking layer before any Elasticsearch-level communication occurs. This error can occur in various scenarios: applications trying to connect to Elasticsearch on localhost when it's not running, Docker containers attempting to reach Elasticsearch on incorrect hostnames or networks, clients connecting to wrong IP addresses, or firewall rules blocking the required ports. The error message typically includes the connection details like host and port being attempted.
First, check if the Elasticsearch service is actually running on the target system:
# For systemd-based systems (Ubuntu, CentOS, Debian)
sudo systemctl status elasticsearch
# Check if the process is running
ps aux | grep elasticsearch
# For Docker environments
docker ps | grep elasticsearchIf the service is not running, start it:
# Systemd
sudo systemctl start elasticsearch
# Docker
docker start <elasticsearch-container-name>After starting, check the logs for startup errors:
# Systemd
sudo journalctl -u elasticsearch -f
# Docker
docker logs -f <elasticsearch-container-name>Use netstat or ss to check if Elasticsearch is actually listening on the port you're trying to connect to:
# Check if port 9200 is listening
sudo netstat -tulpn | grep 9200
# Or using ss (modern alternative)
sudo ss -tulpn | grep 9200
# Expected output should show:
# tcp 0 0 127.0.0.1:9200 0.0.0.0:* LISTEN 12345/javaIf no output appears, Elasticsearch isn't listening on that port. Check if it bound to a different address:
# List all listening ports for elasticsearch process
sudo netstat -tulpn | grep javaAlso test connectivity locally:
# Test from the Elasticsearch server itself
curl -X GET "localhost:9200/"
# If this works but remote connections fail, it's a network binding issueIf Elasticsearch is only listening on localhost (127.0.0.1), remote connections will be refused. Update the network configuration in elasticsearch.yml:
# Edit the configuration file
sudo nano /etc/elasticsearch/elasticsearch.ymlAdd or modify the network.host setting:
# Listen on all interfaces (use for development/testing only)
network.host: 0.0.0.0
# Or bind to specific IP address
network.host: 192.168.1.100
# For Docker environments, use
network.host: 0.0.0.0
network.publish_host: _eth0:ipv4_After changing configuration, restart Elasticsearch:
sudo systemctl restart elasticsearch
# Wait a few seconds and verify it's running
sudo systemctl status elasticsearch
# Test connectivity
curl -X GET "http://YOUR_SERVER_IP:9200/"Important: Setting network.host to 0.0.0.0 changes Elasticsearch from development mode to production mode, which activates bootstrap checks. You may need to configure additional settings like discovery.seed_hosts.
Verify that firewall rules aren't blocking the connection:
# Ubuntu/Debian with ufw
sudo ufw status
# If port 9200 is not allowed, add it:
sudo ufw allow 9200/tcp
# CentOS/RHEL with firewalld
sudo firewall-cmd --list-all
# Add port if needed:
sudo firewall-cmd --permanent --add-port=9200/tcp
sudo firewall-cmd --reload
# Check iptables rules
sudo iptables -L -n | grep 9200For cloud providers, check security groups:
- AWS: Ensure EC2 security group allows inbound traffic on port 9200
- Azure: Check Network Security Group (NSG) rules
- GCP: Verify firewall rules in VPC network
Test connectivity from the client machine:
# Test if port is reachable
telnet YOUR_ES_SERVER_IP 9200
# Or using nc
nc -zv YOUR_ES_SERVER_IP 9200For Docker deployments, ensure proper network configuration:
# docker-compose.yml
version: '3'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
environment:
- discovery.type=single-node
- network.host=0.0.0.0
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- "9200:9200"
- "9300:9300"
networks:
- elastic-network
app:
image: your-app:latest
environment:
# Use service name, not localhost
- ELASTICSEARCH_URL=http://elasticsearch:9200
depends_on:
- elasticsearch
networks:
- elastic-network
networks:
elastic-network:
driver: bridgeKey points for Docker:
1. Applications in other containers should use the service name (elasticsearch:9200), not localhost
2. If connecting from host machine to container, use localhost:9200 with port mapping
3. Containers must be on the same network to communicate
4. Use docker network ls and docker network inspect to verify network setup
Test connectivity between containers:
# From app container to elasticsearch
docker exec -it <app-container> curl http://elasticsearch:9200
# Check if containers are on same network
docker network inspect elastic-networkEnsure your application is using the correct connection details:
// Node.js example - correct configuration
const { Client } = require('@elastic/elasticsearch');
// For Docker environments
const client = new Client({
node: 'http://elasticsearch:9200' // Use service name in Docker
});
// For remote server
const client = new Client({
node: 'http://YOUR_SERVER_IP:9200'
});
// For localhost development
const client = new Client({
node: 'http://localhost:9200'
});# Python example
from elasticsearch import Elasticsearch
# For Docker
es = Elasticsearch(['http://elasticsearch:9200'])
# For remote server
es = Elasticsearch(['http://YOUR_SERVER_IP:9200'])Common connection string mistakes:
- Using localhost when connecting from another container
- Using container IP instead of service name in Docker
- Using https:// when Elasticsearch is configured for http://
- Wrong port number (9200 for HTTP, 9300 for transport)
- Missing host resolution for custom hostnames
Test the connection with a simple query:
# Replace with your actual connection details
curl -X GET "http://YOUR_ES_HOST:9200/_cluster/health?pretty"## Advanced Troubleshooting
### Elasticsearch Startup Issues
If Elasticsearch fails to start, common causes include:
Memory Issues: Check if the JVM heap size is too large for available RAM:
# In jvm.options or via environment variable
-Xms2g
-Xmx2gBootstrap Checks: When binding to non-localhost, Elasticsearch runs bootstrap checks. Common failures:
- Max file descriptors too low: sudo ulimit -n 65535
- Max virtual memory too low: sudo sysctl -w vm.max_map_count=262144
- Insufficient disk space in data directory
### Production Mode Network Configuration
When setting network.host to non-localhost, Elasticsearch enters production mode:
# elasticsearch.yml for cluster setup
cluster.name: my-cluster
node.name: node-1
network.host: 0.0.0.0
http.port: 9200
transport.port: 9300
discovery.seed_hosts: ["192.168.1.100", "192.168.1.101"]
cluster.initial_master_nodes: ["node-1", "node-2"]### Security Considerations
For Elasticsearch 8.x+, security is enabled by default:
# Generate enrollment tokens for new nodes
/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node
# Reset password for built-in users
/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elasticConnection string with authentication:
const client = new Client({
node: 'https://elasticsearch:9200',
auth: {
username: 'elastic',
password: 'your-password'
},
tls: {
ca: fs.readFileSync('./ca.crt'),
rejectUnauthorized: true
}
});### Monitoring Connection Issues
Enable detailed logging to diagnose connection problems:
# elasticsearch.yml
logger.org.elasticsearch.transport: DEBUG
logger.org.elasticsearch.http: DEBUGUse Elasticsearch APIs to check node connectivity:
# Check cluster health
curl -X GET "localhost:9200/_cluster/health?pretty"
# List all nodes
curl -X GET "localhost:9200/_cat/nodes?v"
# Check node stats
curl -X GET "localhost:9200/_nodes/stats?pretty"### Docker Network Debugging
Inspect Docker networks and container connectivity:
# List all networks
docker network ls
# Inspect specific network
docker network inspect elastic-network
# Check container networking
docker exec elasticsearch ip addr show
docker exec elasticsearch netstat -tulpn
# Test DNS resolution between containers
docker exec app-container ping elasticsearch### SELinux/AppArmor Considerations
On systems with SELinux or AppArmor, security policies may block connections:
# Check SELinux status
sestatus
# View denials
sudo ausearch -m avc -ts recent
# Temporarily set to permissive (for testing)
sudo setenforce 0IllegalStateException: There are no ingest nodes in this cluster, unable to forward request to an ingest node
How to fix "There are no ingest nodes in this cluster" in Elasticsearch
NodeDisconnectedException: [node] disconnected
How to fix "NodeDisconnectedException: [node] disconnected" in Elasticsearch
SnapshotException: [repository:snapshot] Snapshot could not be read
How to fix "SnapshotException: [repository:snapshot] Snapshot could not be read" in Elasticsearch
AccessDeniedException: action [cluster:admin/settings/update] is unauthorized
AccessDeniedException: action cluster:admin/settings/update is unauthorized
QueryShardException: No mapping found for [field] in order to sort on
How to fix "QueryShardException: No mapping found for field in order to sort on" in Elasticsearch