Error Medic

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

Last updated:
Last verified:
2,926 words
Key Takeaways
  • 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.
Fix Approaches Compared
MethodWhen to UseTimeRisk
Restart memcached via systemctlService is stopped, inactive, or in a failed state< 1 minLow — no configuration changes
Change bind address (-l flag)Remote clients get ECONNREFUSED but service is running locally5 min + service restartMedium — exposes port if firewall is not configured first
Open firewall port 11211Service running and listening but remote packets are dropped or refused2–5 minMedium — restrict source IPs to trusted subnets only
Increase memory limit (-m flag)OOM kills causing crash loops or high eviction rate in stats output5 min + service restartLow — ensure host has sufficient free RAM before increasing
Increase max connections (-c flag)curr_connections approaches max_connections in `stats` output5 min + service restartLow — verify OS file descriptor ulimit is also raised
Fix SELinux/AppArmor policyService fails to bind after clean install on RHEL, CentOS, or Ubuntu with AppArmor10–20 minHigh — 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 refused
  • MemcachePool::connect(): Can't connect to localhost:11211, Connection refused (111)
  • pylibmc.Error: [11211] Connection refused
  • Errno::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 retries
  • net.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. Run sudo lsof -i :11211 to identify it.
  • failed to daemonize: Permission denied — an OS security framework is blocking the bind. See Step 8.
  • Cannot allocate memory — the requested -m memory 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

bash
#!/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"
E

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

Related Articles in Memcached

Explore More Linux Sysadmin Guides