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);