How to Solve “Failed to Connect to Memcached Host” Error: Connection Refused (111)


3 views

When trying to connect to a Memcached server from a remote host, you might encounter the "Connection refused (111)" error. This typically indicates network-level blocking or incorrect Memcached configuration, even when basic checks like telnet appear successful.

# Verify these common misconfigurations:
1. Memcached binding to localhost only (-l 127.0.0.1)
2. Firewall rules not properly applied
3. SELinux blocking the connection
4. Network interface restrictions
5. Incorrect PHP Memcache extension installation

First, modify your Memcached startup command to listen on all interfaces:

# Original (binding to localhost only):
memcached -u memcached -d -m 30 -l 127.0.0.1 -p 11211

# Corrected version:
memcached -u memcached -d -m 30 -l 0.0.0.0 -p 11211

For production environments, restrict access to specific IPs:

memcached -u memcached -d -m 30 -l 192.168.1.102 -p 11211

Your iptables rules appear correct, but let's ensure they're properly applied:

# For CentOS/RHEL:
sudo service iptables save
sudo service iptables restart

# For Ubuntu/Debian:
sudo iptables-save > /etc/iptables.rules
sudo service netfilter-persistent reload

Verify the rules are active:

sudo iptables -L -n | grep 11211

If using SELinux, you may need to adjust policies:

# Check SELinux status:
getenforce

# Temporarily set to permissive mode for testing:
setenforce 0

# Permanent solution (if connection works in permissive mode):
semanage port -a -t memcache_port_t -p tcp 11211
semanage port -a -t memcache_port_t -p udp 11211

Use this enhanced test script to diagnose connection issues:

<?php
$memcache = new Memcache;
$timeout = 1; // Connection timeout in seconds

if (!@$memcache->connect('192.168.1.102', 11211, $timeout)) {
    $error = error_get_last();
    echo "Connection failed: " . $error['message'] . "<br>";
    
    // Extended diagnostics
    echo "Network check: ";
    echo (fsockopen('192.168.1.102', 11211, $errno, $errstr, $timeout)) 
        ? "Port open" : "Port closed ($errstr)";
    echo "<br>PHP Extension: " . (extension_loaded('memcache') 
        ? "Loaded" : "Missing");
} else {
    echo "Server version: " . $memcache->getVersion() . "<br>";
    // Test read/write operations
    $testKey = 'connection_test_' . time();
    $memcache->set($testKey, 'test_value', false, 10);
    echo "Test value: " . $memcache->get($testKey);
    $memcache->close();
}
?>

If persistent issues remain, try these connection approaches:

// Using persistent connection
$memcache->pconnect('192.168.1.102', 11211);

// With connection pooling (multiple servers)
$memcache->addServer('192.168.1.102', 11211);

// Using UNIX socket if on same host
$memcache->connect('/var/run/memcached.sock', 0);

Verify incoming connections to Memcached:

# Check active connections
netstat -tulnp | grep 11211
ss -tulnp | grep memcached

# Monitor in real-time
watch -n 1 "echo stats | nc 127.0.0.1 11211 | grep curr_connections"

When trying to connect to a Memcached server from a remote host, you might encounter the frustrating "Connection refused (111)" error. This typically indicates that while the service is running locally, it's not properly configured for remote access.

The most common culprit is the binding configuration. Your current command:

memcached -u memcached -d -m 30 -l 127.0.0.1 -p 11211

specifically binds Memcached to localhost only. To allow remote connections:

memcached -u memcached -d -m 30 -l 192.168.1.102 -p 11211

or if you want to listen on all interfaces:

memcached -u memcached -d -m 30 -l 0.0.0.0 -p 11211

While your iptables rules are correct:

-A INPUT -m state --state NEW -m tcp -p tcp --dport 11211 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 11211 -j ACCEPT

You should verify they're actually being applied with:

iptables -L -n -v

Before debugging your PHP code, test basic connectivity:

# From Host B (192.168.1.103)
telnet 192.168.1.102 11211
nc -zv 192.168.1.102 11211

Here's a more robust testing script with error handling:

<?php
$memcache = new Memcache;
$memcache->addServer('192.168.1.102', 11211);

// Set connection timeout (in milliseconds)
$memcache->setCompressThreshold(20000, 0.2);
$memcache->setOption(Memcached::OPT_CONNECT_TIMEOUT, 1000);

if (!@$memcache->connect('192.168.1.102', 11211)) {
    $error = error_get_last();
    echo "Connection failed: " . $error['message'];
    exit;
}

// Test ping
if (!$memcache->getStats()) {
    die("Connected but service not responding");
}

$version = $memcache->getVersion();
echo "Server version: " . htmlspecialchars($version) . "<br>";

// Test read/write
$testKey = 'connection_test_' . time();
if ($memcache->set($testKey, 'test_value', 10)) {
    echo "Write successful<br>";
    $result = $memcache->get($testKey);
    echo "Read back: " . htmlspecialchars($result);
} else {
    echo "Write failed";
}
?>

If you're on CentOS/RHEL, check SELinux status:

sestatus
# Temporarily set to permissive for testing
setenforce 0

To permanently allow memcached network access:

setsebool -P memcached_connect_any on

For more reliable connections, consider using persistent connections:

$memcache->pconnect('192.168.1.102', 11211);

Or using the Memcached class (note the 'd' at the end):

$memcached = new Memcached();
$memcached->addServer('192.168.1.102', 11211);