A cumulative update fails. The Windows Update history shows 0x80073712. Somebody opens a terminal, runs sfc /scannow, waits, then runs DISM /Online /Cleanup-Image /RestoreHealth, waits some more, and reboots. Sometimes it works. Nobody can say why, and nobody can say which component was broken.
That sequence is wrong in three separate ways, and the third one matters most. It is in the wrong order according to Microsoft's own support article. It skips the step that tells you whether the store is corrupt at all. And it is the one operation that rewrites the very evidence you needed to identify the failing component, which means a device that fails again next month starts from zero.
This post is about proving corruption before you repair it. Specifically: what a component manifest is, where manifests live, which part of the servicing stack validates them, how to read the corrupt component's name out of CBS.log, and what the three /Cleanup-Image health switches genuinely do, because most admins have /CheckHealth exactly backwards.
0x80073712 is ERROR_SXS_COMPONENT_STORE_CORRUPT, decimal 14098, and it means a CSI transaction refused to commit because component metadata did not validate. /CheckHealth does not scan anything — it reads a corruption marker in the registry that a previous failed operation already set, and it returns in about a second. /ScanHealth is the actual scan. Run /CheckHealth, then /ScanHealth, then read the corruption block in CBS.log to get the component name, and only then repair. Microsoft documents DISM before SFC, not after. And a clean /CheckHealth result proves nothing about the store — it only proves no marker is set.
The problem: the repair that deletes your evidence
Start with what the code actually says. In WinError.h, decimal 14098 is ERROR_SXS_COMPONENT_STORE_CORRUPT, and the documented message is "The component store has been corrupted." Facility 7 wraps it into the HRESULT you see in the UI, 0x80073712.
Microsoft's own KB947821 describes the same code slightly differently: "The component store is in an inconsistent state." That second phrasing is the more useful one. Inconsistent is not the same as damaged. It means the metadata the servicing stack read did not agree with what the servicing stack expected, and the transaction refused to commit rather than half-apply an update.
Here is the part that catches teams out. Windows repairs this class of fault on its own, silently, and has done since Windows 8. Microsoft's servicing team called the feature Inbox Corruption Repair, and described the automatic path plainly: when corruption is detected while installing fixes via Windows Update, "we'll fix the corruption silently and then re-install the prior packages."
So by the time a human is looking at 0x80073712, one of two things is true: automatic repair already tried and could not source a replacement, or the failure is outside what automatic repair covers. Both cases need the component name. Neither is helped by guessing.
/RestoreHealth is a write operation. It replaces manifests, catalogs and registry data, and it clears the corruption marker on success. Run it first and the only surviving record of which component was broken is the corruption block it wrote into CBS.log during that run — a 12 MB rolling file that gets archived into CbsPersist_*.cab and eventually rolls off. On a recurring fleet fault you have destroyed the trend data you needed. Capture first, repair second.The second problem with the reflex is ordering. The Microsoft support article for System File Checker is explicit: "You should run DISM prior to running the System File Checker." The logic is straightforward once you know the layering. SFC repairs system files by pulling known-good copies from the component store. If the component store itself is inconsistent, SFC is asking a broken source for a good answer. Fix the store, then check the files.
Why it happens: manifests, CSI, and who validates what
The component store is the WinSxS folder, at C:\Windows\WinSxS. Microsoft's own framing is that it exists "to support the functions needed for the customization and updating of Windows" — installing update components, enabling features, moving between editions, recovering from corruption, and uninstalling bad updates. Components track objects such as files, directories, registry keys and services, and specific component versions are collected into packages.
The servicing stack that operates on it has two layers, and knowing which layer failed is most of the diagnosis:
- CBS (Component Based Servicing) works at the package and update level. Its service host is
TrustedInstaller.exe. It decides whether a KB is applicable and hands the components down. - CSI (Component Servicing Infrastructure) works at the deployment and component level. It performs the actual installation, using the Kernel Transaction Manager, and rolls the whole installation back if any part fails.
That distinction is why the log lines matter. A line prefixed CBS is a package-level statement. A line prefixed CSI is a component-level statement. 0x80073712 is raised by CSI and reported by CBS, which is precisely what the documented log excerpt shows.
What a manifest is, and where it lives
A manifest is not a mystery. Microsoft defines manifests as "XML files that accompany and describe side-by-side assemblies or isolated applications," which "uniquely identify the assembly through the assembly's assemblyIdentity element" and "specify the files that make up the assembly." Manifests for shared assemblies are stored in the WinSxS folder.
Critically, a manifest also carries verification data for its files. You can prove that from a sibling error code: 0x800736CC, ERROR_SXS_FILE_HASH_MISMATCH, is documented as "A component's file does not match the verification information present in the component manifest." The manifest is the authority. The binary on disk is the claim being checked.
KB947821 names the exact locations DISM validates, and this is the single most useful paragraph in the whole article:
%SYSTEMROOT%\Servicing\Packages ← package metadata (.mum) and catalogs (.cat)
%SYSTEMROOT%\WinSxS\Manifests ← component manifests (.manifest)
Registry data DISM checks for integrity
HKEY_LOCAL_MACHINE\Components
HKEY_LOCAL_MACHINE\Schema
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing
Two file locations and three registry locations. That is the entire surface. "Component store corruption" always resolves to a problem in one of those five places, and the corruption taxonomy in CBS.log tells you which.
On the Windows 11 test device used for this article, those two directories held 43,198 .manifest files under WinSxS\Manifests, and 7,490 .mum files paired with exactly 7,490 .cat files under servicing\Packages. That one-to-one pairing is not a coincidence, and it is why DISM can emit the message "Repair failed: Missing replacement mum/cat pair." Every package descriptor is expected to have a matching signed catalog.
C:\Windows\WinSxS held two amd64_microsoft-windows-servicingstack_* component directories side by side — 10.0.26100.1 from release, and 10.0.26100.9156 current. The engine binaries inside the newer one all reported 10.0.26100.9156, while TrustedInstaller.exe in C:\Windows\servicing reported 10.0.26100.7019. Different versions in the same servicing path is normal, not a fault.The binaries that actually do the work
Most of the servicing engine is not in System32, which surprises people who go looking for it. It lives inside the versioned servicing-stack component directory in the store. Verified on the test device:
| Binary | Role | Where it lives |
|---|---|---|
TrustedInstaller.exe | CBS service host; the package-level authority | C:\Windows\servicing\ |
CbsCore.dll | The CBS engine itself. Not in System32 | servicing-stack component dir in WinSxS |
TiWorker.exe | Worker process TrustedInstaller spawns to do the servicing work | servicing-stack component dir in WinSxS |
TiFileFetcher.exe | Fetches replacement payload during repair | servicing-stack component dir in WinSxS |
poqexec.exe | Runs the Primitive Operation Queue at boot — the file replacements that could not happen while Windows was running | servicing-stack component dir, and System32 |
drupdate.dll | Driver update handling inside the servicing stack | servicing-stack component dir in WinSxS |
Dism.exe, dismapi.dll | DISM front end and its API surface | C:\Windows\System32\ |
sfc.exe | System File Checker front end | C:\Windows\System32\ |
If TiWorker.exe is pinning a core for twenty minutes, that is the store being walked, not a runaway process. And C:\Windows\WinSxS\pending.xml was absent on the healthy test device, which is the expected state: it only appears when CSI has deferred operations waiting for a reboot.
How to verify: six steps to name the broken component
Work these in order. The goal is not "is it corrupt" — it is "which component, and is it repairable." Do not skip to step four.
Step 1: read the marker. This is not a scan.
Here is the thing almost everyone gets wrong. The current DISM reference says /CheckHealth "Checks whether the image has been flagged as corrupted by a failed process and whether the corruption can be repaired." Note the word flagged. Microsoft's servicing team was blunter about it: /CheckHealth "checks to see if a component corruption marker is already present in the registry," nothing is fixed or logged, and "this operation should be almost instantaneous." They called it a read-only CHKDSK.
The registry surface behind that marker is worth knowing, because it holds history that /CheckHealth never prints. Microsoft documents that DISM checks this key, and documents exactly one value under it (LastResetBase_UTC). The rest of the value names below were read read-only from a live Windows 11 device; Microsoft does not publish their individual semantics, so treat them as corroborating evidence, not as an API.
| Value | Meaning | What to look for |
|---|---|---|
Corrupt observed | The corruption marker /CheckHealth reports on | 0 on a healthy device. Non-zero means a failed operation flagged the store |
AutoRepairNeeded observed | Whether servicing has queued its own repair | 0 healthy. Non-zero means Windows intends to self-repair — give it a chance before you intervene |
PreviousCorruptionDetected observed | Timestamp of the last corruption detection | A FILETIME. Non-zero proves corruption has happened even when Corrupt is 0 |
LifetimeTimesSuccessfullyRepaired observed | Count of successful repairs over the device lifetime | Greater than 0 means Inbox Corruption Repair has silently run. This is your recurrence signal |
LastAutoRepairAttempted observed | Counter for the most recent automatic repair attempt | Correlate against the Setup log events in step 2 |
RepairCategory observed | GUID identifying the repair classification | Changes between repair events; useful only as a fingerprint across a fleet |
LastResetBase_UTC documented | When /ResetBase last ran | Absent means never run. Its presence means update uninstall was surrendered on that device |
LastModified_UTC observed | Last time CBS wrote this key | Should track your last servicing operation. A stale date on a patched device is odd |
EnableLog observed | CBS logging switch | 1 means CBS.log is being written. If it is 0 you have no evidence at all |
The test device read Corrupt = 0 and AutoRepairNeeded = 0 — clean right now. It also read PreviousCorruptionDetected = 134173478872001427, which decodes to 2026-03-07 09:04:47 UTC, and LifetimeTimesSuccessfullyRepaired = 5. This is a fully patched, healthy corporate laptop whose component store has been silently repaired five times, most recently in March, and nobody ever raised a ticket. That is the mechanism working as designed, and it is also why "we've never had store corruption" is usually just "we've never looked."
/CheckHealth does not mean a healthy store. It means no marker is set. A store can be genuinely inconsistent with no marker, because the marker is only written when an operation fails in a way CBS recognises. If your update is failing with 0x80073712 and /CheckHealth says clean, that is not a contradiction and it is not a reason to stop — it is a reason to run step 2.Step 2: run the actual scan, then read the Setup log
/ScanHealth is the real scan: it "checks for component store corruption and records that corruption to the C:\Windows\Logs\CBS\CBS.log but no corruption is fixed using this switch," and it takes roughly five to ten minutes. That is the read-only diagnostic you actually want on a production device, because it produces a log and changes nothing.
It also leaves a durable, timestamped record in the Windows event log that survives the CBS.log rolling off. Almost nobody uses these two events, and they are the cleanest proof artifact in the whole exercise.
| Event ID | Message | What it tells you |
|---|---|---|
| 1013 | "Initiating system store corruption detection and repair. Detection Only: 1, Automatically Triggered: 0." | A corruption scan started. Detection Only: 1 is a detect pass (/ScanHealth); 0 is a repair pass. Automatically Triggered: 0 means a human ran it, not Windows |
| 1014 | "System store corruption detection and repair has completed. Status: 0x0, Total instances of corruption found: 0, total instances of corruption repaired: 0." | The verdict, with counts. Status: 0x0 plus found 0 is your clean result. Found greater than repaired means unrepaired corruption remains |
| 1 | "Initiating changes for package KB<n>. Current state is Staged. Target state is Staged." | A package state transition began. Pair with Event 2 to confirm it finished |
| 2 | "Package KB<n> was successfully changed to the Staged state." | The transition completed. Staged is not Installed — that is normal mid-flight |
| 4 | "A reboot is necessary before package KB5120708 can be changed to the Installed state." | The install is gated on a reboot. This is not a failure and must not be treated as one |
Step 3: read the corruption block in CBS.log
This is where the component name lives. Both /ScanHealth and /RestoreHealth write a structured corruption report into CBS.log, headed "Checking System Update Readiness." Microsoft publishes the format in KB947821, and it looks like this:
Six corruption categories, and each points at a different one of the five locations from step 2. That mapping is the whole diagnostic payoff:
- CBS Manifest / CBS MUM Missing — package metadata under
Servicing\Packages. Often a missing.mum/.catpair. - CBS Metadata — registry data under the Component Based Servicing key.
- CSI Manifest — a
.manifestunderWinSxS\Manifestsis malformed or gone. - CSI Metadata — the component store's own catalogue of deployments.
- CSI Payload — the manifest is valid, the binary it describes is not. This is the
0x800736CChash-mismatch family.
C:\Windows\Logs\DISM\dism.log records what DISM did — which command ran, which provider it loaded, whether it failed. C:\Windows\Logs\CBS\CBS.log records what the servicing stack found — the corruption block, the component names, the CSI transaction errors. KB947821 states DISM's findings go to CBS.log. So when someone says "DISM said corruption was repaired but dism.log doesn't list anything," that is expected: look in CBS.log. On the test device CBS.log was 12.5 MB against a 4.7 MB dism.log, with five archived CbsPersist_*.cab files alongside.Step 4: name the component, then find its KB
Component directory names are structured, and once you can read one you can find its owner. Take wow64_microsoft-windows-audio-volumecontrol_31bf3856ad364e35_10.0.19045.3636_none_4514b27cf12f35d5: architecture, component name, the Microsoft public key token 31bf3856ad364e35, then the version, then language, then a hash. The version segment is the Update Build Revision, and KB947821 documents using it to find the owning update — match the UBR (here 3636) against the Windows release history page, then pull that KB from the Microsoft Update Catalog to source a clean copy.
Step 5: rule out the codes that only look like store corruption
Before you accept "the store is corrupt," check that the code you have actually says that. Several neighbours in the SXS range point somewhere completely different, and treating them all as store corruption sends you down a rebuild path you did not need.
| Code | Symbolic name | What it actually means |
|---|---|---|
0x80073712 | ERROR_SXS_COMPONENT_STORE_CORRUPT | The component store has been corrupted / is in an inconsistent state. This is the one. |
0x800736CC | ERROR_SXS_FILE_HASH_MISMATCH | A file does not match the verification info in its manifest. The manifest is fine, the payload is wrong |
0x800736B4 | ERROR_SXS_MANIFEST_FORMAT_ERROR | The manifest does not begin with the required tag and format information |
0x800736B5 | ERROR_SXS_MANIFEST_PARSE_ERROR | The manifest contains syntax errors. A specific file, not the whole store |
0x800736B3 | ERROR_SXS_ASSEMBLY_NOT_FOUND | The referenced assembly is not installed on the system |
0x80073701 | ERROR_SXS_ASSEMBLY_MISSING | The referenced assembly could not be found |
0x800736FE | ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING | The signed catalog for an assembly is missing. A signing problem, not metadata rot |
0x80073715 | ERROR_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT | Two manifests claim the same identity with different contents |
0x800F080D | CBS_E_MANIFEST_INVALID_ITEM | Invalid CBS manifest entry — package level, not component level |
0x800F081F | CBS_E_SOURCE_MISSING | Repair source unavailable. Your fix failed, not your store. Supply /Source |
0x800F0830 | CBS_E_IMAGE_UNSERVICEABLE | Too damaged to repair. Stop repairing and plan a rebuild or in-place upgrade |
0x800F0984 | PSFX_E_MATCHING_BINARY_MISSING | Component directory exists but the binary is gone. Usually needs an in-place upgrade |
0x8007371B | ERROR_SXS_TRANSACTION_CLOSURE_INCOMPLETE | A servicing transaction was aborted mid-flight |
Step 6: decide repairable or not
Only now is the decision cheap. If /ScanHealth found corruption and named components, and none of your codes are CBS_E_IMAGE_UNSERVICEABLE or PSFX_E_MATCHING_BINARY_MISSING, repair. If /CheckHealth reports the image as non-repairable, Microsoft's guidance is unambiguous: discard the image and start again. And Microsoft's own servicing engineers noted that "a lot of CSI based issues aren't repairable without a repair install," so a stack of CSI Payload findings that /RestoreHealth cannot source is a rebuild signal, not a reason for a fourth attempt.
The fix: repair the component you named, in the documented order
With a component name in hand, the repair is short. Run DISM first, SFC second, per Microsoft's support article.
The PowerShell equivalents are identical in semantics, which matters if you are driving this from a remediation script: Repair-WindowsImage -Online -CheckHealth, -ScanHealth, and -RestoreHealth -Source <paths> -LimitAccess. The cmdlet's -Source accepts multiple paths and uses the first one where the files are found.
0x800F081F failures that get blamed on the store. Fix it with Group Policy or with /Source plus /LimitAccess. And if you do point at a local WIM, it can only supply payloads it actually contains — a WIM at a lower patch level than the device will not repair it.One caution on cleanup. /StartComponentCleanup /ResetBase is not a repair, and it is irreversible: after it completes, existing update packages can no longer be uninstalled. It sets LastResetBase_UTC, which was absent on the test device. Do not reach for it while diagnosing corruption — you are removing the rollback payloads you might need.
Proof it worked: four artifacts, not one exit code
"The operation completed successfully" is the weakest evidence available. Collect four things instead, all read-only, all cheap.
Read those four together and you have an actual finding rather than a vibe. Corrupt = 0 says no marker. A fresh Event 1014 with Status: 0x0 and found 0 says a full scan validated the store, with a timestamp you can put in a ticket. A zeroed CBS.log summary says no category of corruption remains. And the store report gives you the size baseline so that next month's 22.80 GB does not get mistaken for a fault.
The one number worth internalising from that output: 14.79 GB of the 22.80 GB is "Backups and Disabled Features." That is the rollback material Windows keeps so it can undo an update and so Inbox Corruption Repair has something to repair from. The device with the tidiest WinSxS folder is the device with the fewest options when a manifest goes bad.
Finally, record LifetimeTimesSuccessfullyRepaired across your fleet. It cost nothing to read, it is the only durable counter of how often the store has needed rescuing, and a device that has quietly self-repaired five times is telling you something about its disk, its power events or its update interruptions that no single 0x80073712 ticket ever will.
References
- System Error Codes (12000-15999) — the authoritative source for
ERROR_SXS_COMPONENT_STORE_CORRUPT= 14098 (0x3712) and every neighbouring SXS manifest, hash and assembly code used in the differential table. - Fix Windows Update corruptions and installation failures (KB947821) — the two directories and three registry keys DISM validates, the
CBS.logcorruption block format, the corruption categories, and the UBR-to-KB sourcing workflow. - DISM operating system package servicing command-line options — verbatim definitions of
/CheckHealth,/ScanHealth,/RestoreHealth,/AnalyzeComponentStoreand/ResetBase, plus the documentedLastResetBase_UTCvalue. - Repair a Windows Image — the healthy / repairable / non-repairable verdict, the "discard the image" guidance, and the documented scan-then-check ordering.
- Troubleshoot CBS and component store corruption — the log-pattern severity table, the meaning of "Attempting to mark store corrupt," the documented causes, and the
findstr /c:"[SR]"extraction. - Windows Update errors that require in-place upgrades — a full worked
CBS.logexcerpt for0x80073712showing the CSI transaction failing and CBS reporting it. - Manage the Component Store — what the component store is for, how components and packages relate, and why hard linking makes Explorer's size wrong.
- Manifests — the definition of a manifest, the
assemblyIdentityelement, and the statement that shared-assembly manifests live in WinSxS. - Repair-WindowsImage — the PowerShell equivalents, with the same verbatim switch semantics and the multi-path
-Sourcebehaviour. - Use the System File Checker tool — the four documented SFC result strings, the CBS.log path, and the explicit instruction to run DISM before SFC.
- Fixing component store corruption (archived Microsoft servicing blog) — the original engineering description of Inbox Corruption Repair, the "corruption marker already present in the registry" definition of
/CheckHealth, the per-switch timings, and the WSUS repair-source warning. Written for Windows 8 and archived, but the mechanism and the current reference wording still agree.