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:

  1. udpport is non-zero (UDP is listening).
  2. 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

CauseWhat it looks likeFirst thing to check
Pre-1.5.6 install with defaultsSTAT udpport 11211, version below 1.5.6echo "version" | nc localhost 11211
Upgraded but config re-enables UDPVersion 1.5.6+ but udpport still non-zerops flags for -U, and the config file
Container image pinned to old versionFresh deploy shows udpport 11211Image tag and version output
Distro package with UDP default-onRHEL 6/7 or older Debian/Ubuntu without advisory fixPackage 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

  1. Confirm the version. Run echo "version" | nc localhost 11211. If 1.5.6 or later, UDP is off by default and a non-zero udpport means something explicitly set it. If older, UDP was on by default; assume it is exposed unless startup flags prove otherwise.

  2. Check the runtime flag. Run ps -o args -p $(pgrep -x memcached) and look for -U. On 1.5.6+, absence of -U means the default (0) applies. On older versions, absence means the default (11211) applies. Any non-zero -U means UDP is on.

  3. Check the config file. On RHEL-family, inspect /etc/sysconfig/memcached for an OPTIONS line 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 11211 or an OPTIONS string that passes it through.

  4. Check the actual listening sockets. Run ss -lunp | grep 11211. A UDP socket bound to *:11211 or 0.0.0.0:11211 is open on all interfaces. A socket bound to 127.0.0.1:11211 is local-only and not remotely exploitable, but disable it anyway.

  5. 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.

  6. Look for evidence of active abuse. Check bytes_written relative to cmd_get. Active amplification produces extreme write-to-read imbalance: a bytes_written spike 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

SignalWhy it mattersWarning sign
udpport from stats settingsBinary indicator of whether the amplification surface existsAny non-zero value
memcached versionDetermines whether the safe default (UDP off) appliesVersion below 1.5.6
ss -lun output for 11211Confirms the UDP socket is actually open at the OS levelSocket bound to 0.0.0.0:11211 or *:11211
bytes_written / bytes_read ratioActive amplification produces extreme write-to-read imbalancebytes_written spike without proportional cmd_get activity
cmd_get rateBaseline for correlating traffic anomaliesTraffic 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 = 0 in stats settings after every package update.
  • Add udpport to fleet inventory checks. Run stats settings | grep udpport across 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.