Scenario

You've found that your VM / computer has some file corruption issues, and when you're trying to run a windows update or a DISM /RestoreHealth, it reports

C:\Windows\system32>dism.exe /online /cleanup-image /restorehealth

Deployment Image Servicing and Management tool
Version: 10.0.14393.4169

Image Version: 10.0.14393.4169

[==========================100.0%==========================]
Error: 0x800f081f

The source files could not be found.
Use the "Source" option to specify the location of the files that are required to restore the feature. For more information on specifying a source location, see http://go.microsoft.com/fwlink/?LinkId=243077.

The DISM log file can be found at C:\Windows\Logs\DISM\dism.log

You may even try certain combinations of /Source:...install.wim:1 to no avail.

The issue is that the component that needs to be fixed, is not on the source file you have specified. Who knows why it can't get it from Windows Update, but the result is the same - it can't find the right version of the file it needs.

If you do go and check dism.log, you'll get some typically unhelpful log messages:

2023-02-01 02:25:08, Info                  DISM   DISM Package Manager: PID=6968 TID=6156  Error in operation: (null) (CBS HRESULT=0x80070002) - CCbsConUIHandler::Error
2023-02-01 02:25:08, Error                 DISM   DISM Package Manager: PID=6968 TID=1888 Failed finalizing changes. - CDISMPackageManager::Internal_Finalize(hr:0x80070002)
2023-02-01 02:25:08, Error                 DISM   DISM Package Manager: PID=6968 TID=1888 Failed processing package changes with session option CbsSessionOptionAnalyzeStore - CDISMPackageManager::AnalyzeComponentStore(hr:0x80070002)
2023-02-01 02:25:08, Error                 DISM   DISM Package Manager: PID=6968 TID=1888 Failed to analyze component store. - CPackageManagerCLIHandler::ProcessCmdLine_CleanupImage(hr:0x80070002)
2023-02-01 02:25:08, Error                 DISM   DISM Package Manager: PID=6968 TID=1888 Failed while processing command cleanup-image. - CPackageManagerCLIHandler::ExecuteCmdLine(hr:0x80070002)
2023-02-01 02:25:08, Info                  DISM   DISM Package Manager: PID=6968 TID=1888 Further logs for online package and feature related operations can be found at %WINDIR%\logs\CBS\cbs.log - CPackageManagerCLIHandler::ExecuteCmdLine
2023-02-01 02:25:08, Error                 DISM   DISM.EXE: DISM Package Manager processed the command line but failed. HRESULT=80070002

This is, obviously, completely useless to us. Something Happened!. But! The useful information actually lives in C:\Windows\Logs\CBS\cbs.log

2023-02-01 02:25:07, Info                  CBS    Skipping package [OpenSSH-Client-Package~31bf3856ad364e35~amd64~~10.0.17763.1] since it has a release-type [OnDemand Pack] that makes it not superseded
2023-02-01 02:25:07, Info                  CBS    Skipping package [OpenSSH-Server-Package~31bf3856ad364e35~amd64~~10.0.17763.1] since it has a release-type [OnDemand Pack] that makes it not superseded
2023-02-01 02:25:08, Info                  CBS    Failed to load package: Package_for_DotNetRollup~31bf3856ad364e35~amd64~~10.0.3946.2 [HRESULT = 0x80070002 - ERROR_FILE_NOT_FOUND]
2023-02-01 02:25:08, Info                  CBS    Failed to read manifest content. [HRESULT = 0x80070002 - ERROR_FILE_NOT_FOUND]
2023-02-01 02:25:08, Info                  CBS    Failed checking if package is deeply superseded:  [Package_for_DotNetRollup~31bf3856ad364e35~amd64~~10.0.3946.2] [HRESULT = 0x80070002 - ERROR_FILE_NOT_FOUND]
2023-02-01 02:25:08, Info                  CBS    Analyze: Failed to collect packages from package store [HRESULT = 0x80070002 - ERROR_FILE_NOT_FOUND]
2023-02-01 02:25:08, Info                  CBS    Analyze: Failed getting superseded package count [HRESULT = 0x80070002 - ERROR_FILE_NOT_FOUND]
2023-02-01 02:25:08, Info                  CBS    Reboot mark cleared

Aha! We finally find something telling us what is causing DISM so much trouble.

The Investigation

The fix boils down to "Supply DISM the components it needs to fix the issue" or "Re-install that update / component / package".

First thing that needs to happen either way is to find the .msu or .cab etc. for that package.

Alternatively, you might get lucky and the name of the component contains the KB ID of the update that contains the component it needs:

2023-02-02 13:36:43, Error                 CSI    00000001 (F) STATUS_OBJECT_NAME_NOT_FOUND #227620# from Windows::Rtl::SystemImplementation::DirectFileSystemProvider::SysCreateFile(flags = 0, handle = {provider=NULL, handle=0, name= ("null")}, da = (FILE_GENERIC_READ|DELETE), oa = @0xa0a91fcca0->OBJECT_ATTRIBUTES {s:48; rd:NULL; on:[98]'\??\C:\Windows\Servicing\Packages\Package_4944_for_KB5014692~31bf3856ad364e35~amd64~~10.0.2.15.cat'; a:(OBJ_CASE_INSENSITIVE)}, iosb = @0xa0a91fcc40, as = (null), fa = (FILE_ATTRIBUTE_NORMAL), sa = (FILE_SHARE_READ|FILE_S[gle=0xd0000034]
2023-02-02 13:36:43, Error                 CSI    HARE_WRITE|FILE_SHARE_DELETE), cd = FILE_OPEN, co = (FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT), eab = NULL, eal = 0, disp = Invalid)
2023-02-02 13:39:59, Info                  CBS    Repr: Add missing package manifest/cat for package:Package_4944_for_KB5014692~31bf3856ad364e35~amd64~~10.0.2.15
2023-02-02 15:11:53, Info                  CBS    Exec: Not able to find Package_5009_for_KB5014692~31bf3856ad364e35~amd64~~10.0.2.15.mum from directory local source

In these extra examples, we see Package_xxxx_for_KB5014692~31bf3856ad364e35~amd64~~10.0.2.15.cat which means we need to download the .MSU of KB5014692.

In the first case, I needed to find a file that contained components for Package_for_DotNetRollup~31bf3856ad364e35~amd64~~ at version 10.0.3946.2, or perhaps later.

After some googling around, I knew that this was going to be a 20xx-xx Cumulative Update for .NET Framework 3.5 and 4.7.2 for Windows Server 2019 for x64, but I didn't really know which month would work.

If you have an update downloaded that you think might be a candidate, you can download it from https://www.catalog.update.microsoft.com/ and then view the contents of the .msu or .cab with 7-Zip or file-roller (linux). Inside the archive, there is a XML file that describes the components that reside within:

A screenshot of Windows Update file (.MSU) opened in an archive tool. It contains four files, a .cab, .xml, pkgProperties.txt all prefixed with the package name, and WSUSSCAN.cab.

A screenshot of the XML file from the MSU, showing that it's name and version matches the package details I needed.

Bingo!

In this case, it turns out that 2022-05 Cumulative Update for .NET Framework 3.5 and 4.7.2 for Windows Server 2019 for x64 (KB5013641) was exactly the update I needed. I was able to find this after a bit of back-tracking through the update catalog until the numbers lined up.

The Install

Now that we had the update that should Fix It All (TM), we now had to install it.

If the world was a better place, perhaps you could just re-install the update with wusa <<updatefile>>.msu, but alas, because it was "already installed" this did not work.

Using an Update File as the source

Originally I had no luck specifying the exact source to allow DISM to perform the repair online, but luckily (?) I had another machine with more corruption (where the KB5014692 examples come from above), and I was able to find an online method of repair.

Conveniently, while messing around and attempting to repair using the /Source: argument, I was able to trigger the following:

2023-02-02 15:11:53, Info                  CBS    Identity mismatch between package: \\?\C:\Windows\CbsTemp\31012565_543117373\update.mum and identity: Package_5008_for_KB5014692~31bf3856ad364e35~amd64~~10.0.2.15 [HRESULT = 0x800f0818 - CBS_E_IDENTITY_MISMATCH]
2023-02-02 15:11:53, Info                  CBS    Update.mum found from alternate source, but it is not for package Package_5008_for_KB5014692~31bf3856ad364e35~amd64~~10.0.2.15 [HRESULT = 0x800f0818 - CBS_E_IDENTITY_MISMATCH]
2023-02-02 15:11:53, Info                  CBS    Repr: Not able to find replacement manifests for package Package_5008_for_KB5014692~31bf3856ad364e35~amd64~~10.0.2.15 from any local source
2023-02-02 15:11:53, Info                  CBS    Exec: Not able to find Package_5009_for_KB5014692~31bf3856ad364e35~amd64~~10.0.2.15.mum from directory local source
2023-02-02 15:11:53, Info                  CBS    Exec: Not able to find Servicing\Packages\Package_5009_for_KB5014692~31bf3856ad364e35~amd64~~10.0.2.15.mum from directory local source
2023-02-02 15:11:53, Info                  CBS    Exec: Not able to find update.ses from directory local source
2023-02-02 15:11:53, Info                  CBS    Exec: Not able to find Servicing\Packages\update.ses from directory local source

This looks an awful lot like CBS is checking a search path here, and seems to be looking for a few different files:

  • \\?\C:\Windows\CbsTemp\31012565_543117373\update.mum
  • Update.mum found from alternate source
  • Package_5009_for_KB5014692~31bf3856ad364e35~amd64~~10.0.2.15.mum
  • Servicing\Packages\Package_5009_for_KB5014692~31bf3856ad364e35~amd64~~10.0.2.15.mum
  • update.ses
  • Servicing\Packages\update.ses

We'll need to keep an eye out for these file names (particularly update.mum and update.ses) while we're poking around the update files.

If you use 7-Zip (or Windows Explorer) to open the KB5014692 update file, you'll find the following files:

A screenshot of Windows Update file (.MSU) opened in an archive tool. It contains five files, a .cab, .xml, pkgProperties.txt all prefixed with the package name, and SSU-...cab, and WSUSSCAN.cab.

The SSU-...cab is a Servicing Stack Update file, and in this case I didn't think we needed it, so I went straight to opening the Windows10.0-KB5014692-x64.cab file, containing the update specific files.

Opening that, we see

A screenshot of the MSU's CAB file showing another SSU-...cab file, a toc.xml, an update.cat, an update.mum, and another CAB named almost identically.

An update.cat and update.mum! I extracted and copied all of these files, but DISM didn't appear to read the files correctly. Since there was another CAB file there, I extracted that one...

A screenshot of the contents of the CAB from the last CAB, showing three "CAB_x_for_KB...cab" files, an .ini file, an update.cat, and update.mum.

Now this looks like a real update. We have another update.cat and update.mum, and three more CABs. Just to be thorough, I peeked inside one of these CABs:

A screenshot of the contents of the CAB from the last CAB, showing many folders starting with amd64- followed by windows component names.

That looks a lot like the Windows WinSxS folder! I also found something even more promising further down:

A screenshot of the contents of the same CAB as prior, showing many several files starting with package_4944_for_kb5014692....

Perfect! I extracted all three of these CAB files, and didn't even bother copying them to the problematic server. I told DISM to use the source straight off the C$ share of the server I'd been using to poke around, along with the /LimitAccess argument to stop DISM from trying to download the files from Windows Update.

DISM /Online /Cleanup-Image /RestoreHealth /Source:\\server.domain\C$\folder\Windows10.0-KB5014692-v2-x64\Cab_1_for_KB5014692_PSFX /LimitAccess

Note: This command will still work for an offline repair, but you'll obviously need to substitute /Online for the appropriate flags.

(In this case, the destination of the /Source: argument contains the contents of the Cab_x_for... CABs, extracted out and combined into one folder.)

A screenshot showing a successful DISM repair, and behind that window, the DISM log file showing that it's found files in the extra source location.

Finally, we can see that it's managed to repair all of the issues in the logs:

A screenshot of the CBS Log file showing Total Detected Corruption: 54 and Total Repaired Corruption: 54

Offline Package Install

If you have no luck with the source extract method, or just want to try this way, read on.

Since I was running Windows Server 2019, I could not use DISM to apply the update directly to the running OS, but I could do it offline. https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/add-or-remove-packages-offline-using-dism?view=windows-11

First I copied the file to the system - I found it easiest to download it using the running system using powershell.

$ProgressPreference = "SilentlyContinue"
Invoke-WebRequest -UseBasicParsing https://catalog.s.download.windowsupdate.com/c/msdownload/update/software/secu/2022/04/windows10.0-kb5013641-x64_5cf245f52876a8a50a7155fada0245c6d0533bfb.msu -OutFile windows10.0-kb5013641-x64_5cf245f52876a8a50a7155fada0245c6d0533bfb.msu

I booted into the Windows RE environment (by triggering a hard-reset of the VM the moment the spinning dots showed up on the bootscreen, three times), loaded the SCSI driver, and installed the package:

Dism /Image:E: /Add-Package /PackagePath:C:\Users\NRoach44.DA\windows10.0-kb5013641-x64_5cf245f52876a8a50a7155fada0245c6d0533bfb.msu

It finished successfully after a few moments, and I rebooted the machine. It booted up OK, so I ran another /RestoreHealth...

Screenshot of a Windows VM with a running CMD that has two successful DISM commands in it's history.

... and it worked fine!

By far the hardest part of this was identifying the right update to download - I'm not sure if there's a better way (surely there is!) but hopefully a good method shows up at some point.

Addendum: From some initial poking around, it looks like the WSUSSCN2.CAB file, once fully extracted out, has some hits for the Package_for_DotNetRollup string, so if you get stuck, try looking in there for your Component ID.

Conclusion

I've come across DISM source issues a handful of times in my career, and it always bugged me that the tool was clearly stating what the problem was, but the documentation from Microsoft was so lacking that I couldn't give the tool the nudge it needed to fix everything. It was very satisfying to finally be able to fix DISM's component store properly, and restore this machine to fully functioning status!

As a side note, this VM lived on a host with very slow storage. Before doing any of this work, I copied it to my laptop with NVME storage - making all of this nice and quick. It would not surprise me to find out that the slow storage caused this 2022-05 update to fail to install, and then it's just been sitting there failing any updates since then.