You are here because a third party reported your server in a DDoS attack, a security scan flagged UDP 11211, or you are auditing an older deployment. The condition is the same in every case: memcached has UDP enabled (udpport is non-zero) and is reachable from a network you do not control.
This is CVE-2018-1000115. In early 2018 it powered reflection attacks peaking at 1.3 to 1.7 Tbps. A single small UDP GET request with a spoofed source IP can trigger a response of hundreds of kilobytes from an unauthenticated memcached instance, with observed amplification factors around 51,000x. The upstream fix in 1.5.6 (Feb 2018) made udpport default to 0, but that does not retroactively rewrite init scripts, container images, or distro configs.
This is a binary misconfiguration. The remediation path: verify udpport = 0, confirm the bind address is not public, firewall the port, and audit the config so a restart or upgrade does not flip UDP back on.
What this means
Memcached speaks both TCP and UDP. The UDP path exists for large cache clusters where connection overhead matters, which almost no deployment needs. UDP carries no handshake, so an attacker sends a small GET with a spoofed source IP set to the victim’s address. Memcached sends the full cached value back to that address. Because values can be up to 1 MB and the request is tiny, the amplification is enormous.
flowchart LR
A[Attacker] -->|spoofed source IP = victim| B[Memcached UDP 11211]
B -->|response up to 51,000x larger| C[Victim]
C -->|saturated downlink| D[Service outage]The 2018 attacks (“Memcrashed”) used exactly this mechanism. Shodan scans at the time found roughly 88,000 memcached servers with UDP exposed. The vulnerability was assigned CVE-2018-1000115 (CVSS 7.5).
Two conditions must both be true for the attack to work:
udpportis non-zero (UDP is listening).- The UDP port is reachable from the attacker, and the spoofed victim is also reachable.
Disabling either closes the hole. Disabling UDP is the correct fix because almost no workload needs it.
Common causes
| Cause | What it looks like | First thing to check |
|---|---|---|
| Pre-1.5.6 install with defaults | STAT udpport 11211, version below 1.5.6 | echo "version" | nc localhost 11211 |
| Upgraded but config re-enables UDP | Version 1.5.6+ but udpport still non-zero | ps flags for -U, and the config file |
| Container image pinned to old version | Fresh deploy shows udpport 11211 | Image tag and version output |
| Distro package with UDP default-on | RHEL 6/7 or older Debian/Ubuntu without advisory fix | Package version and distro advisory status |
Quick checks
Read-only and safe for production.
# Check the running udpport setting
echo "stats settings" | nc -w2 localhost 11211 | grep udpport
# STAT udpport 0 -> disabled (safe)
# STAT udpport 11211 -> enabled (investigate immediately)
# Check memcached version
echo "version" | nc -w2 localhost 11211
# Inspect the actual startup flags the process is running with
ps -o pid,args -p $(pgrep -x memcached)
# Check whether UDP 11211 is open at the OS level
ss -lunp | grep 11211
# Check TCP bind too (should not be 0.0.0.0 on a public host)
ss -ltnp | grep 11211
# Inspect the config file the service loads
# RHEL-family: /etc/sysconfig/memcached
# Debian-family: /etc/memcached.conf
grep -iE '\-U|\-l|OPTIONS' /etc/sysconfig/memcached /etc/memcached.conf 2>/dev/null
The first line is the most important. If udpport is 0, the amplification surface does not exist regardless of what the config file says. If it is non-zero, proceed to diagnosis.
How to diagnose it
Confirm the version. Run
echo "version" | nc localhost 11211. If 1.5.6 or later, UDP is off by default and a non-zeroudpportmeans something explicitly set it. If older, UDP was on by default; assume it is exposed unless startup flags prove otherwise.Check the runtime flag. Run
ps -o args -p $(pgrep -x memcached)and look for-U. On 1.5.6+, absence of-Umeans the default (0) applies. On older versions, absence means the default (11211) applies. Any non-zero-Umeans UDP is on.Check the config file. On RHEL-family, inspect
/etc/sysconfig/memcachedfor anOPTIONSline containing-U. On Debian-family, inspect/etc/memcached.conf. A common failure mode: the package was upgraded but the old config file still contains-U 11211or anOPTIONSstring that passes it through.Check the actual listening sockets. Run
ss -lunp | grep 11211. A UDP socket bound to*:11211or0.0.0.0:11211is open on all interfaces. A socket bound to127.0.0.1:11211is local-only and not remotely exploitable, but disable it anyway.Confirm external reachability. From a host on an untrusted network, probe the memcached host’s UDP 11211:
nmap -sU -p 11211 <memcached-host>A response means the instance is part of the amplification surface. This is the definitive test.
Look for evidence of active abuse. Check
bytes_writtenrelative tocmd_get. Active amplification produces extreme write-to-read imbalance: abytes_writtenspike with no proportional increase in command rate. A normally read-heavy cache showing a massive write spike is a reflector.
Metrics and signals to monitor
| Signal | Why it matters | Warning sign |
|---|---|---|
udpport from stats settings | Binary indicator of whether the amplification surface exists | Any non-zero value |
| memcached version | Determines whether the safe default (UDP off) applies | Version below 1.5.6 |
ss -lun output for 11211 | Confirms the UDP socket is actually open at the OS level | Socket bound to 0.0.0.0:11211 or *:11211 |
bytes_written / bytes_read ratio | Active amplification produces extreme write-to-read imbalance | bytes_written spike without proportional cmd_get activity |
cmd_get rate | Baseline for correlating traffic anomalies | Traffic that does not match the application’s known access pattern |
Fixes
Disable UDP at the daemon
Set -U 0 in the startup configuration. This is the definitive fix.
On RHEL-family systems, edit /etc/sysconfig/memcached and remove any non-zero -U from the OPTIONS line. On Debian-family systems, edit /etc/memcached.conf and remove any non-zero -U line, or add -U 0 explicitly.
Warning: Restarting memcached means total cache data loss. It does not persist to disk. Plan for a cold-cache period and increased backend load.
On 1.5.6+, if you specify -p (TCP port) without -U, the UDP port does not follow the TCP port. The old coupling was removed in the same commit that changed the default. If your config relied on it, the upgrade may have silently changed your UDP behavior.
Restrict the bind address
Even with UDP disabled, a memcached bound to 0.0.0.0 on a routable IP is a problem. TCP 11211 is unauthenticated by default. Anyone who can reach it can read and write any key, including issuing flush_all.
Use -l 127.0.0.1 for local-only access, or -l <internal-interface-ip> for a specific internal interface. Never bind memcached to a public interface.
Firewall the port
Block both UDP and TCP 11211 from external access at the network firewall, host firewall (iptables, nftables), or cloud security group. This is defense in depth: if the daemon is misconfigured in the future, the firewall still prevents exposure.
Upgrade
Upgrading to 1.5.6 or later makes udpport = 0 the default. But an upgrade alone is insufficient if the config file or init script explicitly passes -U 11211. After any upgrade, re-verify that stats settings shows STAT udpport 0.
Prevention
- Audit after every upgrade. The config file survives upgrades. Re-verify
udpport = 0instats settingsafter every package update. - Add
udpportto fleet inventory checks. Runstats settings | grep udpportacross all instances during deployment validation so a misconfigured node cannot ship. - Pin to 1.5.6+ in container images. Use a base image or tag at 1.5.6 or later, and verify the default held after the build.
- Scan externally. Periodically run a UDP probe against your own memcached hosts from outside the trusted network.
- Firewall by default. Treat port 11211 (UDP and TCP) as internal-only in network policy, regardless of what the daemon reports.
How Netdata helps
Netdata collects memcached stats settings output including udpport as a time-series signal. A non-zero value stands out immediately against a fleet baseline of zeros, turning a one-off manual check into continuous monitoring.
Per-second bytes_written and bytes_read collection lets you correlate write-to-read ratio anomalies against cmd_get rate. An amplification event appears as a bytes_written spike with no corresponding command traffic. Anomaly detection on bytes_written can flag the early stage of a reflection attack even before someone checks udpport manually.
The memcached version is surfaced alongside the settings, so you can see whether an instance predates the 1.5.6 safe default. OS-level socket and network metrics from the same agent let you confirm whether UDP 11211 is actually listening, independent of what the daemon configuration claims.
Related guides
- Memcached cache stampede: a hot key expires and the backend takes the hit
- Memcached evicted_unfetched and expired_unfetched: caching data nobody ever reads
- Memcached cas_badval climbing: check-and-set contention and lost updates
- Memcached command rate anomalies: cmd_get and cmd_set spikes and sudden drops
- Memcached conn_yields rising: one client’s pipeline starving the others
- Memcached connection churn: total_connections racing and TIME_WAIT buildup
- Memcached curr_connections climbing: connection leaks and missing pooling
- Memcached connection limit reached: accepting_conns=0 and clients being refused
- Memcached connection refused: telling a dead process from a hung or full one
- Memcached evicted_time low: distinguishing healthy turnover from cache thrash
- Memcached eviction cascade: when a full cache overloads the backend
- Memcached evictions climbing: the cache is full and discarding live data






