Skip to main content
RunBook Academy

CephCXIII · Multiple OSD FailureMultiple OSD Failure

Reading the shape of a correlated failure

Advanced⏱ ~18 minceph

What you'll learn

  • Group simultaneous failures by CRUSH position
  • Date failures from osdmap epochs
  • Detect flapping before acting on it
  • Recognise when automatic recovery will not start

Prerequisites

None — start here.

Verified against Ceph Tentacle 20.2.x · Ceph Squid 19.2.x (supported previous) · cephadm matches the verified Ceph release · podman 4.x · csi-rbd and csi-cephfs current · RBD / CephFS / RGW current (matches Ceph release) · Linux kernel 5.15+ (5.10 minimum) · Ubuntu 24.04 LTS (Ceph host baseline) · Debian 12 (Bookworm) (Ceph host baseline) · Rocky Linux / RHEL / AlmaLinux 9.x (Ceph host baseline) · Proxmox VE 9.x (cross-course integration) · Kubernetes 1.31+ (cross-course integration) · 2026-08-18

Not yet marked complete on this device.

Why this matters in production

Twenty OSDs down in one rack and twenty scattered across the cluster are opposite problems, and the health output presents them identically.

Grouping by position

ceph osd tree down
ceph osd tree --format json | python3 -c '
import sys,json,collections
t = json.load(sys.stdin)
node = {n["id"]: n for n in t["nodes"]}
parent = {}
for n in t["nodes"]:
    for c in n.get("children", []):
        parent[c] = n["id"]
def up(i, want):
    while i in parent:
        i = parent[i]
        if node[i]["type"] == want:
            return node[i]["name"]
    return "-"
c = collections.Counter()
for n in t["nodes"]:
    if n["type"] == "osd" and n.get("status") == "down":
        c[(up(n["id"], "rack"), up(n["id"], "host"))] += 1
for (r, h), k in sorted(c.items()):
    print("%-12s %-22s %3d down" % (r, h, k))'
ShapeReading
All within one hosta machine
All within one rack, several hostspower, TOR switch, or PDU
Spread evenly across racksa software or fleet-wide change
Two racks, nothing elsethe case CRUSH was not designed for

Dating it from the map

ceph osd dump | grep -E '^osd[.][0-9]+ ' | head -5
osd.23 down out weight 0 up_from 4412 up_thru 4478 down_at 4501 last_clean_interval [4380,4500)
ceph osd dump --format json | python3 -c '
import sys,json,collections
c = collections.Counter(o["down_at"] for o in json.load(sys.stdin)["osds"]
                        if o["up"] == 0)
for e, n in sorted(c.items()):
    print("osdmap epoch %-8d %3d OSDs down" % (e, n))'

The map is a declaration, not a survey

ceph osd crush tree
ceph osd crush tree --show-shadow | head -20
MismatchConsequence
Two CRUSH racks on one PDUa single breaker crosses two domains
Two CRUSH racks on one TOR switcha switch reload does the same
Host moved physically, CRUSH unchangedreplicas believed separated are adjacent
Default CRUSH location from hostnamea rack that exists only in the map

Stabilising first

ceph osd set nodown
ceph log last 200 info cluster | grep -i 'osd[.]'
ceph osd unset nodown
`nodown` stops the monitors acting on failure reports while a fabric is
being repaired. It does not fix anything; it stops the map churning while
you work.

Quiz

Knowledge check · 4 questions

  1. Q1. Why does counting OSDs by their `down_at` epoch identify a correlated failure?

  2. Q2. OSDs in a failed rack are marked out automatically after the down-out interval, exactly as the OSDs of a failed host are.

  3. Q3. Triage a multi-rack OSD failure.

    Health reports 44 OSDs down. It is not yet known whether this is one event or several, and the cluster has been degraded for 25 minutes with no recovery activity.

  4. Q4. What does the CRUSH map fail to tell you about a correlated failure?

Passing score: 75%. Answers are checked in this browser.

Production discipline

Group down OSDs by CRUSH position and by down_at epoch before touching anything — the shape of the failure decides the response. Expect no automatic recovery when a whole rack is down; the subtree limit suppresses it until an operator marks the OSDs out.

Cross-course references

  • Kubernetes: zone labels describe intent, and the scheduler cannot verify the physical topology
  • Linux: two power supplies on one circuit are one power supply