Memcached 'Connection Refused' on Port 11211: Complete Linux Troubleshooting Guide
Fix Memcached Connection refused on port 11211: diagnose stopped services, wrong bind address, firewall blocks, OOM kills, and max connection limits with real c
- Root cause 1: Memcached service is stopped or crashed — verify with `systemctl status memcached` and check `ss -tlnp | grep 11211`; if nothing is listening, start the service with `sudo systemctl start memcached`.
- Root cause 2: Memcached is bound only to 127.0.0.1 — remote clients receive ECONNREFUSED because the daemon is not listening on the reachable network interface; fix with the `-l` flag in /etc/memcached.conf.
- Root cause 3: Host firewall (ufw, firewalld, or iptables) is blocking TCP port 11211 — the service may be running correctly but packets are dropped before reaching the process.
- Root cause 4: The Linux OOM killer terminated Memcached due to memory pressure — check `dmesg -T | grep 'killed process'` and increase the `-m` memory limit in the configuration.
- Quick fix summary: Run `ss -tlnp | grep 11211` to confirm no listener, then `sudo systemctl start memcached`; if it refuses to start, diagnose the crash cause with `journalctl -u memcached -n 50 --no-pager` before changing any configuration.
| Method | When to Use | Time | Risk |
|---|---|---|---|
| Restart memcached via systemctl | Service is stopped, inactive, or in a failed state | < 1 min | Low — no configuration changes |
| Change bind address (-l flag) | Remote clients get ECONNREFUSED but service is running locally | 5 min + service restart | Medium — exposes port if firewall is not configured first |
| Open firewall port 11211 | Service running and listening but remote packets are dropped or refused | 2–5 min | Medium — restrict source IPs to trusted subnets only |
| Increase memory limit (-m flag) | OOM kills causing crash loops or high eviction rate in stats output | 5 min + service restart | Low — ensure host has sufficient free RAM before increasing |
| Increase max connections (-c flag) | curr_connections approaches max_connections in `stats` output | 5 min + service restart | Low — verify OS file descriptor ulimit is also raised |
| Fix SELinux/AppArmor policy | Service fails to bind after clean install on RHEL, CentOS, or Ubuntu with AppArmor | 10–20 min | High — use audit2allow for targeted fix; never disable globally |
Understanding the 'Connection Refused' Error
When a client attempts to connect to Memcached on TCP port 11211 and receives Connection refused (errno ECONNREFUSED), the TCP three-way handshake never completes. The kernel at the target host responded with a RST packet, meaning one of two things: no process is listening on that port, or a firewall rule actively rejected the packet before it reached a socket.
This is distinct from a timeout (where packets are silently dropped by a firewall) or a host unreachable error (routing problem). ECONNREFUSED is deterministic — the host is reachable but the port is closed or blocked.
Common error messages across client stacks:
telnet: connect to address 127.0.0.1: Connection refusedMemcachePool::connect(): Can't connect to localhost:11211, Connection refused (111)pylibmc.Error: [11211] Connection refusedErrno::ECONNREFUSED - Connection refused - connect(2) for "127.0.0.1" port 11211[ERROR] Failed to connect to memcached at 10.0.1.5:11211 after 3 retriesnet.ConnectError: connection refused (os error 111)
Step 1: Confirm Whether Memcached Is Running
Always start here. Configuration changes are useless if the service is not running.
systemctl status memcached
Look for Active: active (running). A status of inactive (dead), failed, or activating (auto-restart) means the process is not serving connections.
Verify at the network layer — confirm nothing is bound to 11211:
ss -tlnp | grep 11211
If this returns no output, no process is listening on port 11211. Proceed to Step 2.
Step 2: Start Memcached and Diagnose Crash Causes
Start the service:
sudo systemctl start memcached
sudo systemctl enable memcached
The enable flag ensures Memcached restarts automatically after a reboot.
If the service fails to start, inspect logs immediately:
journalctl -u memcached -n 100 --no-pager
On older systems without systemd:
tail -n 100 /var/log/syslog | grep -i memcached
tail -n 100 /var/log/messages | grep -i memcached
Common log entries that reveal the root cause:
failed to listen on TCP port 11211: Address already in use— another process owns the port. Runsudo lsof -i :11211to identify it.failed to daemonize: Permission denied— an OS security framework is blocking the bind. See Step 8.Cannot allocate memory— the requested-mmemory exceeds available RAM.
Step 3: Check the Bind Address for Remote Connection Refused
By default on Debian and Ubuntu, Memcached binds exclusively to 127.0.0.1. Any client connecting from a different host will receive ECONNREFUSED even when the service is running perfectly.
Inspect the current bind address:
grep -E '^-l' /etc/memcached.conf
If the output is -l 127.0.0.1, change it to your server's private IP (preferred) or 0.0.0.0 (all interfaces):
sudo sed -i 's/^-l 127.0.0.1/-l 0.0.0.0/' /etc/memcached.conf
sudo systemctl restart memcached
On Red Hat, CentOS, and AlmaLinux, the configuration is /etc/sysconfig/memcached. Edit the OPTIONS line:
OPTIONS="-l 0.0.0.0 -u memcached"
Security warning: Memcached has no built-in authentication. Never bind to a public-facing IP without firewall restrictions. Always restrict access to trusted internal subnets (see Step 4).
Verify the new listener address:
ss -tlnp | grep 11211
# Expected: LISTEN 0 1024 0.0.0.0:11211 0.0.0.0:* users:(("memcached"...))
Step 4: Open Firewall Access to Port 11211
Even with Memcached listening on 0.0.0.0, a host firewall can drop packets silently or reset the connection before they reach the process.
UFW (Ubuntu/Debian):
sudo ufw status verbose
# Open port only for trusted subnet:
sudo ufw allow from 10.10.0.0/24 to any port 11211 proto tcp comment 'memcached'
sudo ufw reload
firewalld (CentOS/RHEL/Fedora):
sudo firewall-cmd --list-all --zone=internal
sudo firewall-cmd --zone=internal --add-port=11211/tcp --permanent
sudo firewall-cmd --reload
iptables (direct):
sudo iptables -L INPUT -n -v | grep 11211
# Add ACCEPT before any DROP rule:
sudo iptables -I INPUT -s 10.10.0.0/24 -p tcp --dport 11211 -j ACCEPT
# Block all other access:
sudo iptables -A INPUT -p tcp --dport 11211 -j DROP
sudo iptables-save | sudo tee /etc/iptables/rules.v4
To confirm a firewall is the problem (versus no listener), use tcpdump from the client side to check whether RST packets or no response is received:
sudo tcpdump -i eth0 -n port 11211
Step 5: Diagnose Out-of-Memory Crash Loops
If Memcached restarts repeatedly, the Linux OOM killer is a frequent culprit. It terminates the highest-scoring memory consumer when the system runs critically low on RAM, and Memcached is often that process.
sudo dmesg -T | grep -i 'killed process' | grep memcached
sudo grep -i 'out of memory' /var/log/syslog | tail -20
A typical OOM kill message looks like:
[Sun Feb 22 04:15:33 2026] Out of memory: Kill process 22148 (memcached) score 881 or sacrifice child
[Sun Feb 22 04:15:33 2026] Killed process 22148 (memcached) total-vm:2097152kB, anon-rss:2048000kB, file-rss:0kB
Check and increase the memory limit in /etc/memcached.conf:
grep '^-m' /etc/memcached.conf
# Default is often -m 64 (64 MB)
sudo sed -i 's/^-m 64/-m 512/' /etc/memcached.conf
sudo systemctl restart memcached
Rule of thumb: allocate no more than 60% of total available RAM to Memcached, leaving headroom for the OS, kernel buffers, and other services.
Step 6: Check Maximum Connections
Memcached defaults to 1024 simultaneous connections. When curr_connections approaches this ceiling, new connection attempts are refused at the application level:
echo 'stats' | nc -q1 127.0.0.1 11211 | grep -E 'curr_connections|max_connections|connection_structures'
If curr_connections is close to max_connections, increase the limit in /etc/memcached.conf:
grep '^-c' /etc/memcached.conf
sudo sed -i 's/^-c 1024/-c 4096/' /etc/memcached.conf
sudo systemctl restart memcached
Also verify the OS file descriptor limit is sufficient for the new value:
cat /proc/$(pgrep memcached)/limits | grep 'open files'
# Or for the current shell:
ulimit -n
The open files limit must be at least max_connections + 10 (for internal file handles).
Step 7: Diagnosing Slow Memcached Performance
If Memcached is running but latency is high or cache effectiveness has dropped, inspect key statistics:
echo 'stats' | nc -q1 127.0.0.1 11211
Critical metrics to evaluate:
| Stat | Healthy Threshold | Problem if Outside Range |
|---|---|---|
evictions |
0 or near-zero | Non-zero means items evicted before TTL — increase -m |
get_hits / (get_hits + get_misses) |
> 80% | Low ratio means cache thrashing or keys expiring too fast |
curr_connections |
< 80% of max_connections | Near-limit causes queuing and latency spikes |
evictions over 1 min window |
< 100/sec | High rate indicates severe memory pressure |
Reset stats and collect a fresh 60-second baseline:
echo 'stats reset' | nc -q1 127.0.0.1 11211
sleep 60
echo 'stats' | nc -q1 127.0.0.1 11211 | grep -E 'evictions|get_hits|get_misses|curr_connections|uptime'
Step 8: SELinux and AppArmor Issues
On SELinux-enforcing systems (RHEL, CentOS, AlmaLinux), Memcached may fail to bind to its port even with correct configuration. The service will appear to start but immediately fail with a permission error.
sudo ausearch -m avc -ts recent | grep memcached
sudo sealert -a /var/log/audit/audit.log | grep -A 10 memcached
Generate a targeted policy module rather than disabling SELinux enforcement:
sudo ausearch -m avc -ts recent | audit2allow -M memcached-custom
sudo semodule -i memcached-custom.pp
For AppArmor on Ubuntu:
sudo aa-status | grep memcached
# Switch to complain mode to diagnose without blocking:
sudo aa-complain /usr/sbin/memcached
journalctl -k | grep -i apparmor | grep memcached
Step 9: Verify End-to-End With a Live Connection Test
After applying any fix, validate the full connection cycle:
# Check port is open:
nc -zv 127.0.0.1 11211
# Read version string:
echo 'version' | nc -q1 127.0.0.1 11211
# Expected: VERSION 1.6.x
# Test set and get round-trip:
printf 'set diag_key 0 300 2\r\nOK\r\n' | nc -q1 127.0.0.1 11211
printf 'get diag_key\r\n' | nc -q1 127.0.0.1 11211
# Expected: VALUE diag_key 0 2\r\nOK\r\nEND
If the connection hangs with no output (versus an immediate refusal), the firewall is dropping packets rather than rejecting them. Run tcpdump -i any port 11211 on the server while the client connects to confirm traffic is arriving.
Frequently Asked Questions
#!/usr/bin/env bash
# memcached-diag.sh — Memcached Connection Refused Diagnostic Script
# Usage: sudo bash memcached-diag.sh [optional-host] [optional-port]
# Defaults: host=127.0.0.1 port=11211
set -euo pipefail
HOST="${1:-127.0.0.1}"
PORT="${2:-11211}"
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BOLD='\033[1m'; NC='\033[0m'
pass() { echo -e " ${GREEN}[PASS]${NC} $*"; }
fail() { echo -e " ${RED}[FAIL]${NC} $*"; }
info() { echo -e " ${YELLOW}[INFO]${NC} $*"; }
echo -e "\n${BOLD}=== Memcached Diagnostic Report ===${NC}"
echo -e "Target: ${HOST}:${PORT}\n"
# --- 1. Service Status ---
echo -e "${BOLD}[1] Service Status${NC}"
if systemctl is-active --quiet memcached 2>/dev/null; then
pass "memcached service is active (running)"
else
fail "memcached service is NOT running"
info "Run: sudo systemctl start memcached"
info "Check crash reason: journalctl -u memcached -n 50 --no-pager"
fi
# --- 2. Network Listener ---
echo -e "\n${BOLD}[2] Port ${PORT} Listener${NC}"
if ss -tlnp | grep -q ":${PORT} "; then
LISTENER=$(ss -tlnp | grep ":${PORT} ")
pass "Process is listening on port ${PORT}"
info "Listener: ${LISTENER}"
else
fail "Nothing is listening on port ${PORT}"
info "Memcached is not running or bound to a different port"
fi
# --- 3. Bind Address ---
echo -e "\n${BOLD}[3] Configured Bind Address${NC}"
for conf in /etc/memcached.conf /etc/sysconfig/memcached; do
if [ -f "$conf" ]; then
BIND=$(grep -E '^-l|OPTIONS' "$conf" | head -3)
info "Config file: $conf"
info "Bind config: ${BIND:-'(not set — defaults to 0.0.0.0)'}"
if echo "$BIND" | grep -q '127.0.0.1'; then
fail "Bound to 127.0.0.1 only — remote clients will be refused"
info "Fix: sudo sed -i 's/^-l 127.0.0.1/-l 0.0.0.0/' $conf && sudo systemctl restart memcached"
fi
fi
done
# --- 4. Memory Configuration ---
echo -e "\n${BOLD}[4] Memory Configuration${NC}"
if [ -f /etc/memcached.conf ]; then
MEM=$(grep -E '^-m ' /etc/memcached.conf | awk '{print $2}')
info "Allocated memory: ${MEM:-64} MB"
TOTAL_MB=$(awk '/MemTotal/{print int($2/1024)}' /proc/meminfo)
info "Host total RAM: ${TOTAL_MB} MB"
fi
# --- 5. OOM Kill Detection ---
echo -e "\n${BOLD}[5] OOM Kill Detection${NC}"
OOM_HITS=$(dmesg -T 2>/dev/null | grep -c 'killed process.*memcached' || true)
if [ "$OOM_HITS" -gt 0 ]; then
fail "OOM killer has terminated memcached ${OOM_HITS} time(s) since last boot"
dmesg -T | grep 'killed process.*memcached' | tail -3
info "Fix: increase -m value in /etc/memcached.conf"
else
pass "No OOM kills detected for memcached in dmesg"
fi
# --- 6. Firewall Check ---
echo -e "\n${BOLD}[6] Firewall Rules for Port ${PORT}${NC}"
if command -v ufw &>/dev/null && ufw status 2>/dev/null | grep -q 'Status: active'; then
RULE=$(ufw status | grep "${PORT}" || echo 'none')
info "ufw rule for ${PORT}: ${RULE}"
elif command -v firewall-cmd &>/dev/null && firewall-cmd --state 2>/dev/null | grep -q running; then
RULE=$(firewall-cmd --list-ports 2>/dev/null | grep "${PORT}" || echo 'none')
info "firewalld port ${PORT}: ${RULE}"
else
RULE=$(iptables -L INPUT -n 2>/dev/null | grep "${PORT}" || echo 'none')
info "iptables rule for ${PORT}: ${RULE}"
fi
# --- 7. Live Connectivity Test ---
echo -e "\n${BOLD}[7] Live Connectivity Test (${HOST}:${PORT})${NC}"
if nc -z -w3 "$HOST" "$PORT" 2>/dev/null; then
pass "Port ${PORT} is open and accepting connections on ${HOST}"
STATS=$(echo 'stats' | nc -q1 "$HOST" "$PORT" 2>/dev/null)
CURR=$(echo "$STATS" | grep 'curr_connections' | awk '{print $3}' | tr -d '\r')
MAX=$(echo "$STATS" | grep 'max_connections' | awk '{print $3}' | tr -d '\r')
EVICT=$(echo "$STATS" | grep '^STAT evictions' | awk '{print $3}' | tr -d '\r')
VER=$(echo "$STATS" | grep 'version' | awk '{print $3}' | tr -d '\r')
info "Memcached version: ${VER:-unknown}"
info "Connections: ${CURR:-?} / ${MAX:-?}"
[ "${EVICT:-0}" -gt 0 ] && fail "Evictions: ${EVICT} (consider increasing -m memory limit)" || pass "Evictions: 0"
else
fail "Cannot connect to ${HOST}:${PORT} — connection refused or timed out"
fi
# --- 8. Recent Log Errors ---
echo -e "\n${BOLD}[8] Recent Memcached Log Entries${NC}"
journalctl -u memcached -n 15 --no-pager 2>/dev/null \
|| grep -i memcached /var/log/syslog 2>/dev/null | tail -15 \
|| info 'No log entries accessible'
echo -e "\n${BOLD}=== Diagnostic Complete ===${NC}\n"Error Medic Editorial
Error Medic Editorial is a team of senior DevOps engineers, SREs, and Linux system administrators with decades of combined experience managing high-traffic production infrastructure. We specialize in actionable troubleshooting guides covering caching layers, database operations, container orchestration, and cloud-native deployments. Our guides are tested against real production failure modes, not synthetic scenarios.
Sources
- https://github.com/memcached/memcached/wiki/ConfiguringServer
- https://github.com/memcached/memcached/wiki/Programming
- https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-memcached-on-ubuntu-20-04
- https://stackoverflow.com/questions/3927/memcached-connection-refused
- https://github.com/memcached/memcached/wiki/ReleaseNotes
- https://linux.die.net/man/1/memcached