LinuxLXXXII · Root Cause AnalysisMethod
Causal chains and stopping rules - not settling for the first plausible answer
What you'll learn
- Build a causal tree rather than a single chain of whys
- Recognise premature closure and the conditions that cause it
- Apply explicit stopping rules to decide when the analysis is complete
- Distinguish a cause that is supported by evidence from one that is merely plausible
Prerequisites
Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-11
An investigation ends when somebody says “ah, that explains it”. That moment is not a discovery, it is a feeling, and it arrives just as reliably for a wrong explanation as for a right one.
This lesson is about not stopping there: how to keep pushing a causal chain, how to notice that you have branched wrongly, and what conditions actually justify closing the analysis.
The problem with five whys
Asking “why” repeatedly is a good instinct with a bad shape. It produces a chain - a single line of reasoning where each answer has exactly one cause - and real incidents do not have that structure.
The API was down.
Why? The certificate had expired.
Why? The renewal job did not run.
Why? The timer was masked.
Why? Someone masked it during a maintenance window.
Why? They forgot to unmask it.
ROOT CAUSE: an engineer forgot to unmask a timer.
Every step is true. The conclusion is useless and it is aimed at a person, which is the reliable sign that the chain went down one branch and never looked sideways.
Three specific defects:
It assumes one cause per level. At “why did the renewal job not run” there were several answers - it was masked, and its failure was not alerted on, and nothing verified the mask was lifted. The chain picked one and discarded the rest.
It stops when the answer becomes uncomfortable. “They forgot” feels like bedrock because the next question sounds accusatory. It is not bedrock; the next question is “what in the system made forgetting possible and consequence-free?”
The number is arbitrary. Five is a slogan. The right depth is set by a stopping rule, and sometimes that is three steps and sometimes it is eight.
Build a tree
Ask, at each node, “what were all the conditions necessary for this?” - and follow more than one branch.
API unavailable for 34 minutes
├── Certificate expired
│ ├── Renewal job did not run
│ │ ├── Timer masked during 2026-06-14 window
│ │ │ └── No procedure step required unmasking, and nothing verified it
│ │ └── Nothing monitors whether scheduled jobs actually ran
│ └── No alert on approaching expiry
│ └── No certificate inventory, so nothing knew what to alert on
├── Failure was total rather than degraded
│ └── Service loads the certificate only at start-up (design constraint)
└── Detection took 17 minutes
├── Synthetic check interval is 15 minutes
└── No alert on the error rate the application already exports
The tree does what the chain cannot: it shows that this incident needed several things to be true at once, and that the cheapest removal is not on the branch the chain followed. “Nothing monitors whether scheduled jobs actually ran” is one check that covers every timer in the estate; “remind engineers to unmask timers” covers one engineer on one occasion.
Plausible is not supported
The distinction that does most of the work in a review:
- Plausible: consistent with what you know. Cheap. Several mutually exclusive explanations are usually plausible at once.
- Supported: there is an observation that would not exist if the explanation were false.
Every node in the causal tree needs to be labelled one or the other, and the honest label for a lot of nodes is “plausible, not verified”.
$ systemctl is-enabled certbot-renew.timer; journalctl -u certbot-renew.service --since '2026-06-01' --no-pager | tail -3masked
Jun 14 02:00:12 app01 systemd[1]: Started certbot-renew.service.
Jun 14 02:00:44 app01 systemd[1]: certbot-renew.service: Succeeded.Illustrative output
Write the label into the review. A tree whose nodes are marked
[supported] and [plausible] tells a reader exactly how much
weight each remediation carries, and it makes the unverified
nodes visible as things to go and check rather than as things
that quietly became facts.
Stopping rules
The analysis is finished when all of these hold. Not before, and
- importantly - not after, because analysis can be continued indefinitely and a review that never closes produces no actions at all.
- Every observation in the timeline is explained, including the ones that did not fit the first story
- At least one node on each branch is supported by evidence rather than only plausible
- You have reached a cause that is general: it explains other incidents, or would have prevented this one across the whole estate rather than on one host
- The next why crosses out of your control - into a vendor, a physical law, or an organisational decision you can name but not change - and you have recorded it as a constraint
- At least one alternative explanation was written down and explicitly refuted
- Each remaining node yields an action that is more specific than the one above it
Rule 6 is the practical test for depth. If asking why again produces an action no more specific than the one you already have, the extra depth is philosophy rather than engineering.
And the counter-rule, for the opposite failure: stop descending when the answers become about people rather than about systems. That is not the bottom of the tree, it is the point at which you branched into blame. Turn the question around
- “what would have made this impossible, or harmless, or obvious?” - and you are back on a branch that produces work.
The other direction: too deep
Reviews can also fail by going too far. “The root cause is that we chose a microservice architecture in 2019” may be true and is not actionable this quarter.
Depth is right when the cause is:
- Within the team or organisation’s ability to change
- Specific enough to imply a concrete action
- General enough that the action prevents a class of incident rather than one instance
Between “the engineer forgot” and “our architecture is wrong” there is a band of causes that are both true and actionable. That band is where the review should land, and rules 3 and 6 above are how you find it.
Knowledge check
Knowledge check · 6 questions
Q1. A five whys analysis concludes that the root cause was an engineer forgetting to unmask a timer. What is the structural defect?
Q2. What is the difference between a plausible cause and a supported one?
Q3. Which of these is a legitimate reason to stop descending the causal tree?
Q4. Which effect of premature closure most directly corrupts the evidence itself?
Q5. Which conditions must hold before a root cause analysis is complete? Select all that apply.
Q6. A causal branch that ends at a vendor defect with no available patch should be left out of the review, since nothing can be done about it.
Passing score: 75%. Answers are checked in this browser.