Refused means the Redis process isn't accepting connections on the port you're hitting. Walk the standard chain — process, bind, protected-mode, firewall — and it's usually a five-minute fix.
systemctl status redis-server and redis-cli ping tell you in ten seconds. Crashes often follow OOM kills or a corrupted AOF on restart — check journalctl -u redis-server -n 50.
Default bind 127.0.0.1 (-::1). If you connect remotely, redis.conf must bind your interface — protected-mode also blocks external connections by default.
localhost:6379 on the host isn't the container's localhost. The port must be published (-p 6379:6379), or the app should join the same docker network and use the service name.
systemctl status redis-server --no-pager; redis-cli -h 127.0.0.1 -p 6379 ping
journalctl -u redis-server -n 50 --no-pager | tail -20 # look for 'Killed', AOF/RDB load errors, or overcommit warnings
# /etc/redis/redis.conf: bind <iface-ip> 127.0.0.1 ; protected-mode yes ; requirepass <strong-secret> ; port 6379
docker run -d --name redis -p 6379:6379 redis:7 # app containers: use 'redis' as hostname on a shared network
Redis refuses to start with a 'Memory overcommit must be enabled' warning on some kernels: sysctl vm.overcommit_memory=1 fixes fork() failures during saves. If Redis only dies under memory pressure, it's the host OOM killer — check kernel logs before blaming Redis.
Default bind is loopback-only and protected-mode blocks external clients. Set bind to include the right interface, keep protected-mode on with a requirepass, then reload: systemctl restart redis-server.
Refused = host reachable, nothing listening (process down or bind/port mismatch). Timeout = packets dropped (firewall, wrong host). That distinction cuts your debug time in half.
Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.
Browse the template store →One-time. Yours to modify. Instant download from the NinjaOps template store.