← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-21863 · CWE-125 · Disclosed 2026-02-23

Valkey is a distributed key-value database

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a fire alarm you can only pull after you get into the staff hallway

CVE-2026-21863 is an out-of-bounds read in Valkey clusterbus packet parsing that can terminate the valkey-server process when a malformed cluster PING extension is received. Authoritative records disagree slightly on the 9.0.x fix boundary, but the affected ranges consistently include pre-fix clustered Valkey branches around 7.2.x, 8.0.x, 8.1.x, and 9.0.x; the published fixed builds are 7.2.12, 8.0.7, 8.1.6, and either 9.0.2 per NVD/CPE text or 9.0.3 per the GitHub advisory and release notes.

The vendor-style AV:N/PR:N/UI:N label overstates enterprise urgency because it ignores where the vulnerable surface actually lives: the *cluster bus* port, not the normal client port. In real fleets this is usually node-to-node traffic on private networks, often firewalled, and the impact is process crash/DoS rather than code execution or data theft, so this scores as a downgrade from HIGH to MEDIUM despite the low-complexity packet trigger.

"Unauthenticated on paper, but real exploitation usually requires access to an internal cluster-only port."
02 · The Attack Path

3 steps from start to impact.

STEP 01

Find a reachable cluster bus listener with nmap or masscan

The attacker first needs TCP reachability to the Valkey cluster bus, which by default is the data port plus 10000 and is commonly 16379. This is not the standard client interface; it exists for node-to-node cluster traffic and may also be set with cluster-port.
Conditions required:
  • Target is running Valkey in cluster mode
  • Attacker can route to the cluster bus port from their network position
  • Firewall or security group allows inbound TCP to that port
Where this breaks in practice:
  • Many enterprise deployments keep cluster traffic on private subnets only
  • Cluster bus port may be non-default if cluster-port is customized
  • Standalone Valkey/Redis deployments are out of scope
Detection/coverage: External attack-surface scanners often miss this if the bus port is non-default; internal ASM and port inventory are more reliable than version-only vuln scans.
STEP 02

Send a malformed cluster PING extension using a custom packet generator

Valkey's cluster spec says nodes always accept connections on the cluster bus and reply to PING even from untrusted nodes. A custom TCP client can therefore speak just enough of the binary cluster bus protocol to deliver an invalid extension packet without needing cluster membership or application credentials.
Conditions required:
  • Attacker can open a TCP session to the cluster bus
  • Target branch is one of the vulnerable pre-fix builds
  • Attacker can craft the cluster bus frame format
Where this breaks in practice:
  • This is not a commodity HTTP exploit; it needs protocol-specific packet crafting
  • TLS on cluster links can add another hurdle if enabled and enforced
  • Most opportunistic botnets do not target internal cluster protocols
Detection/coverage: Network IDS can key on unexpected inbound connections to cluster bus ports from non-cluster IPs; host logs may emit warnings on invalid packet length/extension parsing.
STEP 03

Trigger the out-of-bounds read and crash the process

The bug is a bounds-check failure around clusterbus ping extension parsing. The fix adds length validation before reading extension data; without it, a malformed packet can drive an invalid read and terminate the server process, causing node-level DoS and possible failover churn.
Conditions required:
  • Malformed frame reaches vulnerable parsing path
  • Process is not already patched or backported
  • Crash handling or HA does not fully absorb the failure
Where this breaks in practice:
  • Impact is availability-only; there is no evidence here of RCE or auth bypass
  • Well-designed clusters may fail over and reduce blast radius to one node
  • Process supervision can restart the daemon, limiting outage duration
Detection/coverage: Crash loops, systemd restarts, container restarts, and cluster failover events are the practical signals; version scanners may flag broad ranges but won't prove exploitability without network-path context.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo evidence located of active exploitation. The user-supplied intel says KEV listed: No, and I found no primary-source exploitation bulletin from CISA, Valkey, or cloud vendors.
Proof-of-concept availabilityNo public weaponized PoC was found in primary sources during review. The GitHub fix commit includes regression tests and enough protocol detail for a competent operator to build a packet generator, so *DIY exploitability is plausible even without a turnkey repo*.
EPSSUser-supplied EPSS is 0.0002 (~0.02%), which is extremely low and matches the narrow exposure pattern.
KEV statusNot in CISA KEV per user-supplied intel; no date added because there is no listing.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H = easy packet trigger *if reachable*, but that vector does not model that the reachable surface is usually an internal cluster-only port.
Affected versionsNVD CPE data says vulnerable versions are <7.2.12, 8.0.0-8.0.6, 8.1.0-8.1.5, and 9.0.0-9.0.1.
Fixed versionsGitHub advisory/release notes publish fixes in 7.2.12, 8.0.7, 8.1.6, and 9.0.3. Debian backports include valkey 8.1.1+dfsg1-3+deb13u2; Amazon Linux 2023 fixed package is listed under ALAS2023-2026-1471.
Versioning discrepancyWatch the 9.0.x branch carefully. NVD text/CPE implies 9.0.2 is fixed, while the GitHub advisory and Valkey release notes say patched 9.0.3. For defenders, treat 9.0.2 as UNKNOWN until your package source confirms the backport.
Scanning / exposure realityThe cluster bus defaults to data port +10000 and is commonly 16379, but it is intended for node-to-node traffic only. Because cluster-port is configurable and many clusters stay private, internet scan counts from Shodan/Censys-style views will *under-represent* total enterprise exposure while still confirming that accidental exposure of 16379/tcp is a real class of mistake.
Disclosure / creditPublished 2026-02-23. GitHub advisory credits 0x Kato.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.8/10)

The decisive friction is that the bug lives on the Valkey *cluster bus* rather than the normal client interface, which sharply reduces the reachable population in disciplined enterprise deployments. This is still worth fixing because unauthenticated malformed traffic can crash a node, but it is mostly a post-exposure or misconfiguration problem, not a broad internet-grade emergency.

HIGH Severity downgrade driven by attacker-position and exposure friction
MEDIUM Exact 9.0.x fixed boundary because NVD and GHSA disagree

Why this verdict

  • Downgrade for attacker position: the attacker needs network reachability to the cluster bus, which is typically private east-west infrastructure traffic rather than an internet-facing service.
  • Downgrade for exposed population: only clustered Valkey nodes are in play; standalone deployments and fleets that never enable cluster mode are not reachable on this path.
  • Downgrade for blast radius: the demonstrated impact is node crash / DoS, not code execution, data theft, or tenant escape.
  • Downgrade for controls already expected in modern estates: NGFWs, security groups, Kubernetes network policies, and host firewalls should already restrict cluster-to-cluster ports to known peers.
  • No upgrade from threat intel: no KEV listing, no primary-source active exploitation evidence, and the user-provided EPSS is very low.

Why not higher?

If this were on the standard client port or if there were active exploitation against internet-exposed caches, this could justify HIGH. But the prerequisite chain compounds downward: cluster mode, reachable cluster bus, and a narrow protocol path that normally sits behind internal ACLs.

Why not lower?

This is not just theoretical. Nodes explicitly accept cluster bus connections and reply to PING from untrusted peers, the bug is low-complexity once the port is reachable, and crashing a database node can still cause real customer-facing pain in sharded or latency-sensitive environments.

05 · Compensating Control

What to do — in priority order.

  1. Lock down the cluster bus — Allow inbound cluster bus traffic only from known Valkey peer IPs or subnets using host firewall rules, security groups, or network ACLs. For a MEDIUM verdict there is no mitigation SLA, so do this in the next normal network-hardening change window if you cannot patch immediately.
  2. Hunt for non-default cluster ports — Do not assume only 16379; find any configured cluster-port values in config management, container manifests, and service definitions. This closes the blind spot where scanners look only for the default port; again, no mitigation SLA applies at MEDIUM, but this belongs in routine exposure-reduction work.
  3. Alert on non-peer connections — Create detections for inbound TCP sessions to cluster bus ports from IPs outside the cluster membership list. This gives you fast signal on recon or malformed packet testing while you work through normal remediation scheduling.
  4. Validate HA restart behavior — Confirm systemd, orchestrator health checks, or container supervision restart the process cleanly and that failover does not thrash the cluster. This does not fix the bug, but it reduces operational blast radius while you move toward patching.
What doesn't work
  • AUTH / client ACLs do not solve this path because the issue is on the cluster bus protocol, not normal client command authentication.
  • A WAF is irrelevant; this is raw TCP cluster protocol traffic, not HTTP.
  • Protected mode on the client listener is not a reliable control for cluster bus exposure; you still need explicit network restrictions on the bus port.
06 · Verification

Crowdsourced verification payload.

Run this on the target Valkey host as a normal user; root is only needed if you want package-manager fallback checks. Save it as check-cve-2026-21863.sh, then run bash check-cve-2026-21863.sh /usr/bin/valkey-server or just bash check-cve-2026-21863.sh to auto-discover the binary. It outputs VULNERABLE, PATCHED, or UNKNOWN and exits 0, 1, or 2 respectively.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-cve-2026-21863.sh
# Determine likely exposure to CVE-2026-21863 on a Valkey host.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

TARGET="${1:-}"

find_bin() {
  if [[ -n "$TARGET" && -x "$TARGET" ]]; then
    echo "$TARGET"
    return 0
  fi
  for b in /usr/bin/valkey-server /usr/local/bin/valkey-server /bin/valkey-server; do
    [[ -x "$b" ]] && { echo "$b"; return 0; }
  done
  command -v valkey-server 2>/dev/null && return 0
  return 1
}

BIN="$(find_bin 2>/dev/null || true)"
if [[ -z "$BIN" ]]; then
  echo "UNKNOWN: valkey-server binary not found"
  exit 2
fi

RAWVER="$($BIN --version 2>/dev/null | head -n1)"
VER="$(printf '%s' "$RAWVER" | sed -n 's/.*v=\([0-9][0-9.]*\).*/\1/p')"

if [[ -z "$VER" ]]; then
  echo "UNKNOWN: could not parse version from: $RAWVER"
  exit 2
fi

IFS='.' read -r MAJ MIN PAT <<< "$VER"
MAJ="${MAJ:-0}"; MIN="${MIN:-0}"; PAT="${PAT:-0}"

ver_ge() {
  # usage: ver_ge a.b.c x.y.z
  local A B C X Y Z
  IFS='.' read -r A B C <<< "$1"
  IFS='.' read -r X Y Z <<< "$2"
  A=${A:-0}; B=${B:-0}; C=${C:-0}; X=${X:-0}; Y=${Y:-0}; Z=${Z:-0}
  if (( A > X )); then return 0; fi
  if (( A < X )); then return 1; fi
  if (( B > Y )); then return 0; fi
  if (( B < Y )); then return 1; fi
  (( C >= Z ))
}

ver_lt() {
  ! ver_ge "$1" "$2"
}

is_vuln=1
reason="not in affected branch"

# Affected ranges from NVD/GHSA, with special caution on 9.0.2 because sources disagree.
if ver_lt "$VER" "7.2.12"; then
  is_vuln=0
  reason="version is below 7.2.12"
elif ver_ge "$VER" "8.0.0" && ver_lt "$VER" "8.0.7"; then
  is_vuln=0
  reason="version is in 8.0.0-8.0.6"
elif ver_ge "$VER" "8.1.0" && ver_lt "$VER" "8.1.6"; then
  is_vuln=0
  reason="version is in 8.1.0-8.1.5"
elif ver_ge "$VER" "9.0.0" && ver_lt "$VER" "9.0.2"; then
  is_vuln=0
  reason="version is in 9.0.0-9.0.1"
elif [[ "$VER" == "9.0.2" ]]; then
  echo "UNKNOWN: version 9.0.2 sits in an advisory discrepancy (NVD suggests fixed; GHSA/release notes point to 9.0.3). Verify vendor/backport status."
  exit 2
fi

# Package manager hint for distro backports.
PKG_HINT=""
if command -v dpkg-query >/dev/null 2>&1; then
  PKG_HINT="$(dpkg-query -W -f='${Package} ${Version}\n' valkey 2>/dev/null || true)"
elif command -v rpm >/dev/null 2>&1; then
  PKG_HINT="$(rpm -q valkey 2>/dev/null || true)"
fi

if [[ -n "$PKG_HINT" ]]; then
  case "$PKG_HINT" in
    *deb13u2*|*8.1.1+dfsg1-3+deb13u2*|*ALAS2023* )
      echo "PATCHED: distro package appears backported/fixed ($PKG_HINT)"
      exit 0
      ;;
  esac
fi

if (( is_vuln == 0 )); then
  echo "VULNERABLE: parsed Valkey version $VER ($reason)"
  exit 1
fi

# Conservative patched logic.
if ver_ge "$VER" "9.0.3"; then
  echo "PATCHED: parsed Valkey version $VER"
  exit 0
elif ver_ge "$VER" "8.1.6" && ver_lt "$VER" "9.0.0"; then
  echo "PATCHED: parsed Valkey version $VER"
  exit 0
elif ver_ge "$VER" "8.0.7" && ver_lt "$VER" "8.1.0"; then
  echo "PATCHED: parsed Valkey version $VER"
  exit 0
elif ver_ge "$VER" "7.2.12" && ver_lt "$VER" "8.0.0"; then
  echo "PATCHED: parsed Valkey version $VER"
  exit 0
fi

echo "UNKNOWN: version $VER is outside known vulnerable ranges but package/backport status could not be confirmed"
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: inventory only clustered Valkey nodes, then verify whether any cluster bus ports are reachable from anything other than approved peer nodes; if they are, close that exposure in the next normal firewall/network change because this is a MEDIUM with noisgate mitigation SLA: no mitigation SLA — go straight to the 365-day remediation window. For patching, standardize on vendor- or distro-confirmed fixed builds (7.2.12, 8.0.7, 8.1.6, and treat 9.0.2 with caution unless your supplier confirms it; otherwise use 9.0.3) and complete upgrades within the noisgate remediation SLA of 365 days, prioritizing any internet- or cross-segment-exposed cluster bus listeners first.

Sources

  1. GitHub Security Advisory GHSA-c677-q3wr-gggq
  2. Valkey fix commit 4169393
  3. NVD CVE-2026-21863
  4. Valkey cluster specification
  5. Valkey security documentation
  6. Valkey releases
  7. Debian security tracker entry
  8. Amazon Linux Security Center CVE entry
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.