Fix: Redis ECONNREFUSED – Connection Refused on localhost:6379
Quick Answer
How to fix the Redis ECONNREFUSED error when your application cannot connect to the Redis server on localhost:6379 or a remote host. Covers Redis not running, wrong host/port, Docker networking, firewall, AUTH required, maxclients, and TLS configuration.
The Error
You try to connect to Redis and get:
Error: connect ECONNREFUSED 127.0.0.1:6379Or one of these variations:
Error: connect ECONNREFUSED ::1:6379Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED 127.0.0.1:6379Could not connect to Redis at 127.0.0.1:6379: Connection refusedNOAUTH Authentication requiredERR max number of clients reachedError: Redis connection lost and command aborted. It might have been processed.All of these mean the same underlying problem: your client cannot establish or maintain a connection to the Redis server. Either Redis is not running, the connection details are wrong, something is blocking the connection, or Redis is rejecting it for a specific reason.
Why This Happens
Redis listens for connections on port 6379 by default. When your client sends a TCP connection request and nothing is listening at that address and port, the operating system responds with a “connection refused” error, which surfaces as ECONNREFUSED in Node.js and similar environments.
Common causes:
- Redis is not running. The service was never started, crashed, or was stopped during a system update. This is the number one cause.
- Wrong host or port. Your application is trying to connect to
localhost:6379but Redis is listening on a different interface or port. - Docker networking. Your app is running inside a Docker container and
localhostresolves to the container itself, not the host machine or the Redis container. - Firewall blocking port 6379. A firewall rule is silently dropping or rejecting the connection before it reaches Redis.
- Redis requires authentication. Redis is reachable but requires a password via the
AUTHcommand, and your client is not sending one. maxclientslimit reached. Redis has hit its maximum number of simultaneous client connections and is refusing new ones.- TLS/SSL mismatch. Redis is configured for TLS-only connections but your client is connecting without TLS, or the other way around.
- Redis is bound to a specific interface. By default, Redis binds to
127.0.0.1, rejecting connections from other machines or from Docker containers using the host’s network IP. - IPv6 vs IPv4 resolution. On some systems,
localhostresolves to::1(IPv6) but Redis is only listening on127.0.0.1(IPv4).
Fix 1: Start Redis
The most common cause. Redis simply is not running.
Linux (systemd):
sudo systemctl start redisOn some distributions, the service is called redis-server:
sudo systemctl start redis-serverCheck the status:
sudo systemctl status redisIf it is not enabled to start on boot:
sudo systemctl enable redismacOS (Homebrew):
brew services start redisCheck the status:
brew services list | grep redisWindows:
If you installed Redis via the official Windows port or Memurai, open Services (Win+R, type services.msc), find the Redis service, right-click, and select Start.
Or from an elevated Command Prompt:
net start RedisFor WSL-based Redis:
sudo service redis-server startVerify Redis is listening:
redis-cli pingIf Redis is running, you get:
PONGIf it is not running, you get:
Could not connect to Redis at 127.0.0.1:6379: Connection refusedYou can also check the port directly:
# Linux / macOS
ss -tlnp | grep 6379
# Windows (PowerShell)
netstat -an | findstr 6379If nothing is listening on 6379, Redis is not running. Check the logs to find out why:
# Linux
sudo tail -50 /var/log/redis/redis-server.log
# macOS (Homebrew)
tail -50 /opt/homebrew/var/log/redis.logCommon startup failures:
- Data directory permissions. Redis cannot write to its data directory. Fix with:
sudo chown -R redis:redis /var/lib/redis
sudo chmod 770 /var/lib/redis- Corrupt RDB or AOF file. Redis refuses to start if its persistence file is corrupted. Check the logs for messages like
Bad data formatorBad file format reading the append only file. You can attempt a repair:
redis-check-rdb /var/lib/redis/dump.rdb
redis-check-aof --fix /var/lib/redis/appendonly.aof- Another process is using port 6379. Check what is using the port:
sudo lsof -i :6379Kill the conflicting process or change the Redis port in redis.conf.
Fix 2: Check the Host and Port Configuration
Your application may be connecting to the wrong address or port. Redis defaults to 127.0.0.1:6379, but this can be changed in redis.conf.
Check what Redis is actually listening on:
redis-cli INFO server | grep tcp_port
redis-cli INFO server | grep bindOr look at the config file directly:
grep -E "^(bind|port)" /etc/redis/redis.confA typical config looks like:
bind 127.0.0.1 -::1
port 6379If Redis is listening on a non-default port, update your application’s connection configuration:
// Node.js with ioredis
const Redis = require('ioredis');
const redis = new Redis({
host: '127.0.0.1',
port: 6380 // match whatever Redis is actually using
});# Python with redis-py
import redis
r = redis.Redis(host='127.0.0.1', port=6380)If your connection details come from environment variables, make sure those variables are actually loaded. A common mistake is forgetting to call dotenv.config() before reading process.env.REDIS_URL. If the variable comes back as undefined, your Redis client falls back to defaults that may not match your setup. See Fix: Environment Variable Is Undefined for more on this.
Fix 3: Fix Docker Networking
If your application runs inside a Docker container and Redis runs on the host machine or in another container, localhost inside your container refers to the container itself, not the host or other containers. This is one of the most common causes of ECONNREFUSED in containerized environments.
Connecting to Redis on the host from a container
Docker Desktop (macOS/Windows):
redis://host.docker.internal:6379Linux:
docker run --add-host=host.docker.internal:host-gateway myappThen use host.docker.internal as the Redis host in your application.
Connecting between containers with docker-compose
Use the service name as the hostname, not localhost:
services:
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis-data:/data
app:
build: .
environment:
REDIS_URL: redis://redis:6379
depends_on:
- redis
volumes:
redis-data:The hostname is redis (the service name), not localhost. Your app connects to redis:6379, and Docker’s internal DNS resolves it to the Redis container’s IP.
Redis container is not ready yet
If your app starts before Redis finishes initializing, the connection fails. Add a health check so that depends_on waits for Redis to be truly ready:
services:
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
app:
build: .
environment:
REDIS_URL: redis://redis:6379
depends_on:
redis:
condition: service_healthyContainers on different networks
If your app container and Redis container are on different Docker networks, they cannot reach each other. Make sure both services share the same network:
services:
redis:
image: redis:7-alpine
networks:
- backend
app:
build: .
networks:
- backend
networks:
backend:For more on Docker Compose startup and networking problems, see Fix: Docker Compose Up Errors and Fix: Docker Container Not Connecting.
Real-world scenario: In Docker Compose setups, the most common mistake is using
localhostor127.0.0.1as the Redis host from your application container. Inside a container,localhostrefers to the container itself — not the host machine or other containers. Always use the Docker Compose service name (e.g.,redis) as the hostname.
Fix 4: Configure the Firewall
A firewall may be silently dropping connections to port 6379 before they reach Redis. This is especially common on cloud servers (AWS, GCP, Azure) where security groups or firewall rules are restrictive by default.
UFW (Ubuntu/Debian):
sudo ufw allow 6379/tcp
sudo ufw reloadfirewalld (RHEL/Fedora/CentOS):
sudo firewall-cmd --add-port=6379/tcp --permanent
sudo firewall-cmd --reloadiptables:
sudo iptables -A INPUT -p tcp --dport 6379 -j ACCEPTAWS Security Groups:
In the AWS Console, go to your instance’s security group and add an inbound rule for TCP port 6379 from your application’s IP or security group.
Important: Never expose Redis port 6379 to the public internet without authentication and encryption. Redis has no built-in protection against unauthorized access by default. If you need remote access, use SSH tunneling or a VPN:
# SSH tunnel to access remote Redis locally
ssh -L 6379:127.0.0.1:6379 user@remote-serverThen connect to localhost:6379 on your local machine, and the traffic is forwarded through the SSH tunnel.
Fix 5: Set Up Redis Authentication
If Redis requires a password, connecting without one produces:
NOAUTH Authentication requiredOr if you provide the wrong password:
WRONGPASS invalid username-password pair or user is disabledCheck if AUTH is enabled
Look at redis.conf:
grep "^requirepass" /etc/redis/redis.confIf it returns something like requirepass mysecretpassword, authentication is enabled.
In Redis 6+, ACLs (Access Control Lists) replace the simple requirepass mechanism. Check ACL users:
redis-cli ACL LISTConnect with authentication
redis-cli:
redis-cli -a mysecretpasswordOr after connecting:
AUTH mysecretpasswordWith Redis 6+ ACLs:
AUTH username passwordNode.js (ioredis):
const Redis = require('ioredis');
// Simple password
const redis = new Redis({
host: '127.0.0.1',
port: 6379,
password: 'mysecretpassword'
});
// Redis 6+ ACL with username
const redis = new Redis({
host: '127.0.0.1',
port: 6379,
username: 'myuser',
password: 'mysecretpassword'
});Using a Redis URL:
// Without username (pre-Redis 6)
const redis = new Redis('redis://:[email protected]:6379');
// With username (Redis 6+ ACL)
const redis = new Redis('redis://myuser:[email protected]:6379');Python (redis-py):
import redis
r = redis.Redis(
host='127.0.0.1',
port=6379,
password='mysecretpassword',
username='myuser' # Redis 6+ ACL only
)If your password is stored in an environment variable, make sure it is loaded correctly. A missing or empty password variable will cause silent authentication failures. See Fix: Environment Variable Is Undefined to debug this.
Fix 6: Handle maxclients Limit
When Redis hits its maxclients limit, new connections are refused:
ERR max number of clients reachedCheck the current limit and active connections
redis-cli INFO clientsLook for:
connected_clients:150
maxclients:128If connected_clients is at or near maxclients, you have hit the limit.
Increase maxclients
In redis.conf:
maxclients 10000Or set it at runtime without restarting:
redis-cli CONFIG SET maxclients 10000Note that the OS file descriptor limit (ulimit -n) must be higher than maxclients + 32 (Redis reserves 32 file descriptors for internal use). Increase it if needed:
# Check current limit
ulimit -n
# Set temporarily
ulimit -n 65535For a persistent change on Linux, add to /etc/security/limits.conf:
redis soft nofile 65535
redis hard nofile 65535And for systemd-managed Redis, create an override:
sudo systemctl edit redisAdd:
[Service]
LimitNOFILE=65535Fix connection leaks
The real problem is usually not a low maxclients value but a connection leak in your application. Common causes:
- Creating a new Redis connection for every request instead of reusing a single client or connection pool.
- Not closing connections in serverless functions. AWS Lambda and similar environments reuse containers, and connections pile up.
- Missing error handlers. When a connection errors out without being caught, the socket may linger.
Check for idle connections:
redis-cli CLIENT LISTLook for clients with a high idle value (in seconds). Kill idle clients with:
redis-cli CLIENT KILL ID <id>Or configure Redis to close idle connections automatically:
timeout 300This closes client connections that have been idle for 300 seconds.
Fix 7: Fix TLS/SSL Configuration
Redis 6+ supports TLS natively. If your Redis server requires TLS and your client connects without it (or the other way around), the connection fails silently and surfaces as ECONNREFUSED or a timeout.
Check if Redis uses TLS
Look at redis.conf:
grep -E "^(tls-port|tls-cert-file|tls-key-file)" /etc/redis/redis.confIf tls-port is set (commonly to 6380), Redis expects TLS on that port. The regular port (6379) may be disabled entirely with port 0.
Connect with TLS
redis-cli:
redis-cli --tls --cert /path/to/client.crt --key /path/to/client.key --cacert /path/to/ca.crt -p 6380Node.js (ioredis):
const Redis = require('ioredis');
const fs = require('fs');
const redis = new Redis({
host: '127.0.0.1',
port: 6380,
tls: {
ca: fs.readFileSync('/path/to/ca.crt'),
cert: fs.readFileSync('/path/to/client.crt'),
key: fs.readFileSync('/path/to/client.key')
}
});For Redis services that use TLS on the standard port with publicly trusted certificates (like AWS ElastiCache or Upstash), you typically only need:
const redis = new Redis({
host: 'your-redis-host.cache.amazonaws.com',
port: 6379,
tls: {},
password: 'your-auth-token'
});Passing an empty tls: {} object enables TLS without requiring custom certificates.
Using a rediss:// URL:
The rediss:// scheme (note the double s) indicates a TLS connection:
const redis = new Redis('rediss://:password@your-redis-host:6380');Python (redis-py):
import redis
r = redis.Redis(
host='127.0.0.1',
port=6380,
password='mysecretpassword',
ssl=True,
ssl_certfile='/path/to/client.crt',
ssl_keyfile='/path/to/client.key',
ssl_ca_certs='/path/to/ca.crt'
)Self-signed certificate errors
If you get certificate verification errors with a self-signed cert in development:
const redis = new Redis({
host: '127.0.0.1',
port: 6380,
tls: {
rejectUnauthorized: false // Development only!
}
});Never disable certificate verification in production. It makes you vulnerable to man-in-the-middle attacks.
Fix 8: Update the Bind Address
By default, Redis binds to 127.0.0.1, which means it only accepts connections from the local machine. If your application runs on a different machine (or in a Docker container accessing the host network), the connection is refused.
Check the current bind address:
grep "^bind" /etc/redis/redis.confTo accept connections from all interfaces:
bind 0.0.0.0Or to accept connections from specific interfaces:
bind 127.0.0.1 192.168.1.100After changing redis.conf, restart Redis:
sudo systemctl restart redisWarning: If you bind to 0.0.0.0, make sure requirepass or ACLs are enabled. Also enable protected-mode as an additional safeguard:
protected-mode yesWith protected-mode yes, Redis rejects connections from external interfaces unless a password is set. This prevents accidentally exposing an unprotected Redis instance to the network.
Still Not Working?
IPv6 vs IPv4
On some systems, localhost resolves to ::1 (IPv6) instead of 127.0.0.1 (IPv4). Redis may only be listening on IPv4.
Error: connect ECONNREFUSED ::1:6379Fix by using 127.0.0.1 explicitly instead of localhost:
const redis = new Redis({
host: '127.0.0.1', // not 'localhost'
port: 6379
});Or configure Redis to listen on both IPv4 and IPv6:
bind 127.0.0.1 ::1Redis Sentinel or Cluster misconfiguration
If you are using Redis Sentinel for high availability, make sure your client is connecting through the Sentinel, not directly to a replica:
const redis = new Redis({
sentinels: [
{ host: 'sentinel-1', port: 26379 },
{ host: 'sentinel-2', port: 26379 },
{ host: 'sentinel-3', port: 26379 }
],
name: 'mymaster', // Sentinel master name
password: 'redis-password'
});For Redis Cluster:
const Redis = require('ioredis');
const cluster = new Redis.Cluster([
{ host: 'node-1', port: 6379 },
{ host: 'node-2', port: 6379 },
{ host: 'node-3', port: 6379 }
]);If the cluster topology changed (nodes added or removed) and your client has stale configuration, it will try to connect to nodes that no longer exist. Restart your application to force a topology refresh.
Connection timeouts vs connection refused
If you get a timeout instead of ECONNREFUSED, the problem is different. ECONNREFUSED means a TCP RST was received (nothing is listening). A timeout means the packet was sent but no response came back, which usually points to a firewall dropping packets or a network routing issue.
Add a connectTimeout to surface these faster:
const redis = new Redis({
host: '127.0.0.1',
port: 6379,
connectTimeout: 5000, // fail after 5 seconds instead of hanging
retryStrategy(times) {
const delay = Math.min(times * 200, 5000);
return delay; // retry with increasing delay, max 5 seconds
}
});Redis crashed and won’t restart
Check the Redis log for the reason:
sudo journalctl -u redis --no-pager -n 50Common crash causes:
- Out of memory. Redis stores everything in RAM. If it exceeds available memory, the OS OOM killer terminates it. Set
maxmemoryinredis.confto prevent this:
maxmemory 256mb
maxmemory-policy allkeys-lruCorrupt persistence file. As mentioned in Fix 1, use
redis-check-rdborredis-check-aof --fixto repair.Huge pages warning. Redis logs may show a warning about Transparent Huge Pages (THP). Disable THP:
echo never > /sys/kernel/mm/transparent_hugepage/enabledManaged Redis services (ElastiCache, Cloud Memorystore, Upstash)
If you are using a managed Redis service, the connection details are different from a local Redis install:
- AWS ElastiCache is only reachable from within the same VPC. You cannot connect from your local machine without an SSH tunnel or VPN.
- GCP Cloud Memorystore requires the connecting service to be in the same VPC or to use a private service connection.
- Upstash and Redis Cloud are accessible over the internet but require TLS and authentication.
For ElastiCache, a common pattern is to SSH tunnel through a bastion host:
ssh -L 6379:your-cluster.abc123.cache.amazonaws.com:6379 ec2-user@bastion-hostThen connect to localhost:6379 locally.
If your Nginx reverse proxy sits in front of an app that uses Redis, a Redis connection failure can cascade into an Nginx 502 Bad Gateway error for end users. Always check Redis connectivity first when debugging 502 errors from backend services.
For similar database connection troubleshooting, see Fix: MongoDB ECONNREFUSED. If your system is hitting file descriptor limits, see Fix: ENOSPC System Limit for File Watchers.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: .env File Not Loading – dotenv Variables Are Undefined in Node.js, Python, or Docker
How to fix .env files not being loaded by dotenv, Next.js, Vite, Django, or Docker Compose, including wrong file path, missing dotenv.config(), and variable naming issues.
Fix: WRONGTYPE Operation against a key holding the wrong kind of value (Redis)
How to fix Redis errors: WRONGTYPE Operation against a key holding the wrong kind of value, MISCONF Redis is configured to save RDB snapshots, OOM command not allowed, READONLY You can't write against a read only replica, and other common Redis errors. Covers key type mismatches, disk issues, memory limits, eviction policies, connection problems, and serialization.
Fix: Docker Build Cache Not Working - No Cache Being Used
How to fix Docker build cache not working when layers rebuild every time despite no changes, including layer ordering, .dockerignore, COPY invalidation, BuildKit cache mounts, and CI/CD cache strategies.
Fix: Cannot Connect to the Docker Daemon. Is the Docker Daemon Running?
How to fix the 'Cannot connect to the Docker daemon' error on Linux, macOS, and Windows, including Docker Desktop, systemctl, WSL2, and Docker context issues.