DEV Community

Rafael Ruiz Coutiño
Rafael Ruiz Coutiño

Posted on

WinUI 3 Startup Crash (0xC000027B): How We Fixed a Missing resources.pri

WinUI 3 Startup Crash (0xC000027B): How We Fixed a Missing resources.pri

A real-world debugging case involving Windows App SDK, unpackaged applications, and self-contained deployment.

During the development of a WinUI 3 desktop application, we encountered a persistent startup failure.

The application terminated unexpectedly before displaying its user interface. The diagnostic logs pointed to Microsoft.UI.Xaml.dll, with the exception code 0xC000027B.

Initially, this appeared to be a runtime issue, a version incompatibility, or an internal XAML initialization failure.

After several controlled experiments, however, we discovered something different: the application was building successfully, but the publishing process was not correctly generating the resource index required at runtime.

We are sharing this investigation because other developers may encounter similar symptoms.

  1. The Symptoms

Our environment used WinUI 3, Windows App SDK, and an unpackaged, self-contained, x64 deployment model.

During the investigation, we encountered several error codes:

  • 0xC000027B
  • 0x80004005
  • 0x80070002

The process could terminate within:

  • Microsoft.UI.Xaml.dll
  • Microsoft_UI_Xaml!FailFastWithStowedExceptions

In one of our diagnostic experiments, the failure occurred while constructing:

Microsoft.UI.Xaml.Controls.XamlControlsResources

We also encountered the following error message:

Cannot find a resource with the given key: AcrylicBackgroundFillColorDefaultBrush

These symptoms do not necessarily share a single underlying cause.

In our case, however, they provided important clues that eventually led us to a resource resolution problem.

  1. First, We Isolated the Application from the Framework

Instead of continuing to modify the entire application, we created minimal diagnostic probes to identify the first operation that failed.

The results were revealing:

Stage Result
Runtime initialization PASS
Application creation PASS
Basic XAML component creation PASS
XamlControlsResources construction FAIL
Empty resource dictionary PASS
Minimal window without the problematic initialization path PASS

This investigation allowed us to reproduce the failure without loading the original application’s business logic.

That distinction was essential because it significantly narrowed the search space.

  1. A Common Trap: Testing Different Versions Does Not Mean Loading Different Runtimes

We also investigated whether the failure depended on a specific Windows App SDK version.

Several experiments requested different minimum runtime versions.

However, when we inspected the DLL actually loaded by the process, we discovered that the different configurations ultimately resolved to the same physical version of Microsoft.UI.Xaml.dll.

This led to an important conclusion:

Changing the requested runtime version does not prove that a different runtime is actually being executed.

In environments that use dynamic dependencies, developers must verify both the selected runtime package and the actual DLLs loaded by the process.

Otherwise, what appears to be a comparison between multiple runtime versions may simply be repeated testing against the same runtime.

  1. The Breakthrough: resources.pri

The decisive discovery came when we examined the build and publishing pipeline.

The build process generated an application-specific PRI resource index, but the published output did not correctly contain the expected root file:

resources.pri

With the resource map:

Application

In other words, generating resources during compilation was not enough.

The publishing process also needed to produce and deliver the correct resource index in the expected location.

To verify this, we performed a controlled comparison.

Test A: Without the correct PRI

Resource resolution failed, and the application could not complete startup initialization.

Test B: With the correct PRI included

Resource resolution succeeded, and the application started successfully.

Test C: Removing only resources.pri

The resource resolution failure returned.

Test D: Restoring the correct published output

The application started working again.

These experiments provided much stronger causal evidence than simply observing exception code 0xC000027B.

  1. The Fix: Integrating MakePri into the Publish Pipeline

The solution was to integrate PRI generation into the reproducible publishing process.

The tool we used was:

MakePri.exe

Microsoft documents this mechanism for unpackaged applications that need to generate an appropriate resources.pri file.

The general generation pattern is:

makepri.exe new
/pr "<RESOURCE_DIRECTORY>"

/cf ""
/in Application

/of "\resources.pri" `
/o

Illustrative example: directories and configuration must be adapted to the specific project.

In our case, the essential changes were:

  • Integrating PRI generation into the MSBuild publishing process.
  • Using an appropriate MakePri configuration for the unpackaged deployment model.
  • Omitting the section from that configuration.
  • Enabling the necessary PRI indexer to include resources from referenced dependencies.
  • Generating the root resource map named Application.
  • Placing resources.pri alongside the published executable.
  • Ensuring that both application resources and WinUI resources remained accessible.

We did not need to reinstall Windows App SDK, modify packages inside WindowsApps, or manually copy files from an installed runtime.

The fix became part of the build and publishing process rather than depending on manual intervention after publication.

  1. An Additional Safeguard: Preventing Stale PRI Files

The initial fix allowed the application to start, but we identified another potential risk.

What happens if a previous publication leaves behind a valid resources.pri file and a subsequent MakePri execution fails?

A poorly controlled publishing process could retain the old file and incorrectly appear to have succeeded.

To prevent this, we added a safeguard that ensures a residual PRI file cannot be accepted as newly generated output.

We validated this behavior through specific tests:

  1. Successful clean publication.
  2. Publication with an existing PRI file.
  3. Deliberate MakePri failure.
  4. Recovery followed by a clean publication.
  5. Regression testing against previously working behavior.

The publishing process correctly rejected the MakePri failure and did not accept the outdated file as a newly generated artifact.

This protection is particularly important in automated publishing pipelines, especially when output directories are reused.

  1. How We Verified the Fix

We did not consider a successful build exit code sufficient evidence that the problem had been resolved.

We also inspected the physical published output and verified the application’s runtime behavior.

Our validation included:

Verification Result
Two clean publishing runs PASS
Automatically generated PRI index PASS
Reproducible results PASS
Root resource map: Application PASS
Application resources PASS
WinUI resources PASS
Executable startup PASS
Main window visible PASS
Normal process shutdown PASS
Remaining processes 0
New events matching the investigated failure None detected

We also used MakePri to inspect the generated indexes:

makepri.exe dump
/if "<PUBLISH_DIRECTORY>\resources.pri"

/of "\resources.xml"

This allowed us to examine the actual contents of the resource index instead of assuming that a file named resources.pri was necessarily valid.

  1. What We Learned

This incident provided several lessons that may be useful in other WinUI 3 projects.

Lesson 1: An exception inside Microsoft.UI.Xaml.dll does not automatically indicate a Microsoft framework defect.

The framework may simply be where an underlying resource or deployment problem becomes visible.

Lesson 2: Build, publish, and runtime are separate stages.

A project can compile successfully while still producing an incomplete deployment.

Lesson 3: PRI structure matters in unpackaged applications.

The presence, location, and structure of the resource index can be critical to successful resource resolution.

Lesson 4: Runtime version comparisons require verification.

Requesting different Windows App SDK versions does not guarantee that different binaries are actually being loaded.

Lesson 5: Negative tests are extremely valuable.

Removing a single dependency, reproducing the failure, and restoring that dependency can establish causal relationships that diagnostic logs alone may not reveal.

Lesson 6: Reproducible fixes belong in the pipeline.

Manually copying a missing file may be useful as a diagnostic experiment, but it should not become a hidden requirement for successful deployment.

  1. What to Check If You Encounter a Similar Failure

If your unpackaged WinUI 3 application crashes during XAML resource initialization, consider checking the following:

  • Does the required bootstrap or runtime initialization complete successfully for your deployment model?
  • Can the failure be reproduced in a minimal application with valid XAML initialization?
  • Which physical version of Microsoft.UI.Xaml.dll is actually loaded by the process?
  • Does the published output contain resources.pri?
  • Does the resource index contain the correct root map for your deployment scenario?
  • Can both application resources and referenced dependency resources be resolved?
  • Does MakePri execute during publication, and are its failures correctly propagated?
  • Does removing only the resource index reproduce the failure in an isolated negative test?

We do not recommend copying files from WindowsApps, modifying installed runtimes, or randomly switching SDK versions before isolating the actual defect.

Conclusion

In our case, resolving the startup failure did not require changes to the application’s core logic.

The operational root cause was an incomplete PRI resource index integration within the unpackaged publishing process.

Once we correctly generated resources.pri using MakePri and included it in the published application, startup worked again.

The main takeaway is straightforward:

When WinUI 3 fails during resource initialization, do not investigate only your XAML code or runtime version. Inspect what your publishing pipeline is actually producing.

This is a specific debugging case, not a universal explanation for error 0xC000027B.

Other applications may encounter the same exception code for entirely different reasons.

Official Documentation and References

For additional technical background, refer to Microsoft Learn:

  • Localization and resources for unpackaged applications
  • MRT Core and PRI resource files
  • Self-contained deployment with Windows App SDK

We hope this experience helps other developers identify a problem that, at first glance, can appear considerably more complex than it actually is.

Top comments (0)