When working on enterprise-grade multi-project .NET solutions, maintaining strict version alignment across your framework and NuGet packages is critical. During a recent deployment of a .NET 9 web application to a Kubernetes cluster, a sudden runtime crash occurred, throwing a FileNotFoundException during application startup.

This article explores how to diagnose this dependency conflict, understand how transitive dependencies pull in unexpected framework versions, and apply a clean, permanent fix.

1. The Symptom: Runtime Crash & Kubernetes CrashLoopBackOff

Upon deploying an updated build, the Kubernetes pods immediately entered a CrashLoopBackOff state. Inspecting the pod logs via terminal revealed an unhandled exception:

Plaintext

Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb93829ddae60'.
File name: 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=10.0.0.0...'
   at NTL.OWS.Presentation.Program.Main(String[] args)

Even though the solution was explicitly targeted at .NET 9.0, the runtime environment was looking for Version 10.0.0.0 of the dependency injection abstractions assembly[cite: 1].

2. Uncovering the Root Cause: Transitive Dependencies and NuGet Conflict (NU1605)

Inspecting the Solution Explorer and NuGet Package Manager revealed that while the primary projects targeted .NET 9.0 with packages pinned to 9.0.x, a newly added third-party library introduced a hidden conflict.

  • The Transitive Culprit: The project included PDFsharp (7.0.0-preview-1) and PDFsharp-MigraDoc.

  • Hidden Dependencies: Prerelease or preview builds of third-party libraries often pull in newer transitive packages. In this case, PDFsharp silently brought down Microsoft.Extensions.Logging.Abstractions (10.0.5), which subsequently dragged in .NET 10 dependency injection abstractions.

  • The Restore Error (NU1605): When attempting to manually override or downgrade the logging abstractions back to 9.0.19, NuGet flagged a package downgrade error:

    Plaintext

    NU1605: NTL.OWS.Presentation -> PDFsharp 7.0.0-preview-1 -> Microsoft.Extensions.Logging.Abstractions (>= 10.0.5)[cite: 7]
    

3. Step-by-Step Resolution

To resolve this issue and ensure runtime stability across your .NET 9 environment, follow these steps:

Step 1: Identify Prerelease or Mismatched Packages

Examine your Solution Explorer under your projects' Dependencies > Packages tree. Look for any packages carrying preview tags (like -preview) or version numbers that deviate from your target framework stack.

Step 2: Downgrade Preview Libraries to Stable .NET-Compatible Versions

Avoid using preview libraries that depend on newer runtime frameworks unless strictly required.

  1. Open the NuGet Package Manager in Visual Studio.

  2. Select both PDFsharp and PDFsharp-MigraDoc.

  3. Downgrade them from 7.0.0-preview-1 to a stable, .NET 9 compatible version (such as 6.5.0).

Step 3: Clean and Restore the Solution

Once the conflicting preview packages are aligned with your target framework, clear your local NuGet caches and rebuild the solution:

Bash

dotnet nuget locals all --clear
dotnet clean
dotnet restore

4. Bonus Tip: Configuring Swagger for Production Environments

When building APIs, ensuring middleware like Swagger remains accessible during testing or production monitoring is often necessary. If you need Swagger to function seamlessly across both Development and Production pipelines without encountering a 404 Not Found error, configure your middleware in Program.cs as follows:

C#

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

// Enable Swagger middleware across environments
app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "NTL.OWS API v1");
    c.RoutePrefix = "swagger"; // Accessible via /swagger
});

Conclusion

Dependency version mismatches in enterprise applications can be tricky because transitive packages often pull in newer framework components beneath the surface. By keeping a vigilant eye on your NuGet dependency tree, avoiding unwanted preview packages that target mismatched major versions, and enforcing strict version parity (9.0.x), you can prevent runtime crashes like FileNotFoundException and keep your container deployments healthy.