Kernel Taint Flags: Preserve Prior Events When Comparing Crash Reproductions
Decode taint as accumulated boot context, then locate the earlier event that set each relevant flag. A tainted kernel is not automatically unusable, and a taint letter does not identify the cause of the current crash. It tells the investigator which prior conditions may affect interpretation or reproduction.
This article is pinned to upstream Linux v6.12. Distributions and later kernels can add or interpret context differently, so preserve the raw integer and printed string with the exact build. The numerical worksheet below is synthetic; no kernel taint state was changed or read from a target.
Collect taint at more than the final failure
The v6.12 taint guide describes a persistent record of relevant conditions. Unloading a module or undoing another visible action does not erase the boot’s taint history. This matters when a later test appears to run without the component that originally changed the kernel state.
Capture the raw value from /proc/sys/kernel/tainted at the beginning of the reproduction, before the suspected trigger and after the first failure when collection remains possible. Save the warning’s own printed taint field too. The later live value can include events that occurred after the warning being analyzed.
Keep boot identity, kernel/module hashes, command line and event timestamps with those snapshots. A before/after comparison across different boots is not an accumulated-state transition. Nor does a crash archive from the previous boot describe the current recovery kernel’s taint.
Decode bits with the matching version
The integer is a bitfield, not a severity score or error count. The upstream v6.12 decoding helper can accept a supplied value for offline analysis. Use the matching version and retain its input rather than relying on a screenshot of a translated description.
| Illustrative v6.12 bit | Mask | Meaning relevant to a reproduction |
|---|---|---|
| 9, W | 512 | A kernel warning occurred |
| 12, O | 4096 | An externally built module was loaded |
| 0, P when set | 1 | A proprietary-module condition was recorded |
These are selected examples, not a complete table. The printed G in the first position indicates that the proprietary-module bit is clear; it does not imply that every other taint bit is clear. Preserve spaces and positions when decoding a printed field, or prefer the exact integer when available.

Work a synthetic before/after example
Suppose the baseline value is 4096 and the later value is 4608 in the same boot. The later value contains 4096 plus 512: the out-of-tree-module condition remains, and a warning condition has appeared. The newly set bit mask is after & ~before, which is 512 for these nonnegative integer inputs.
A local integer-only fixture checked that decomposition and the new-bit calculation. It did not call kernel interfaces, reproduce a warning or validate a real device. The arithmetic proves how this example decodes; it cannot identify which warning occurred or why.
If a third snapshot remains 4608 after module unload, that is consistent with retained taint history. It is not evidence that the module is still loaded. If another warning occurs, the same bit can remain set, so unchanged taint does not mean no new warning happened.
Build a provenance timeline
Use a row for each observed transition: boot/run identifier, timestamp, raw value, newly observed bits, nearest supporting log event and confidence. Where the earlier log was lost, mark the source of a bit unknown rather than guessing from the currently loaded modules.
Distinguish the event that sets a flag from the event that crashes later. A prior warning may point to the real first failure, while a later null dereference is a consequence. An out-of-tree module may be unrelated. The timeline should preserve both possibilities until source or reproduction evidence separates them.
Do not assign exact timing to a bit from one final snapshot. A bit has no embedded occurrence timestamp, and it does not count repeated events. The surrounding log and deliberate baseline observations provide chronology.
Compare reproductions without hiding necessary components
- Record the original failing configuration and its taint before the trigger.
- Identify which taint-producing components or prior events can be excluded without removing the behavior under investigation.
- Use a separate clean boot for a reduced configuration and verify the relevant workload still executes.
- Run the same trigger and compare both the first failure and the taint timeline.
- Keep the original configuration as evidence even if the reduced one no longer reproduces.
An upstream-only kernel can be valuable for isolating a defect, but a custom board may need a vendor driver to exercise its device. Removing that driver and observing no crash does not establish that the vendor driver caused the original failure. It may simply remove the path entirely.
If a fully untainted reproduction is impractical, describe the required known baseline honestly. A repeatable test that starts with one explained condition is more useful than a claim of cleanliness created by omitting inconvenient context.
Avoid causal shortcuts
A warning bit says a warning occurred, not that every later result is invalid in the same way. A machine-check-related flag deserves the actual hardware report; it is not sufficient to name a failed DIMM. A test-related flag can reflect deliberate diagnostic activity rather than an unsolicited field fault.
Similarly, a zero value does not certify correctness or exclude hardware defects. It only indicates that no taint conditions are recorded in that value. A bug can crash an initially untainted kernel, and a valid workload can run on a kernel with an explained diagnostic condition.
Deliver a reproducible context record
Attach raw values, decoded bits, exact decoder revision, complete first-failure logs and the timeline of configuration changes. Explain why each reduced test still represents the original operation. Preserve unresolved origins as open questions rather than replacing them with a module blame label.
The outcome is a comparison another engineer can reproduce: which boot conditions differed, which failure remained, and which earlier events were retained. Taint improves that provenance when treated as history, not as a numerical measure of fault severity.