Method not found: ‘Void Microsoft.IdentityModel.Tokens.TokenValidationResult..ctor

# Technical Postmortem: MissingMethodException in Blazor Web App During OIDC Token Validation

## Summary
A Blazor Web App targeting .NET 9.0 failed during authentication with a `System.MissingMethodException` when calling `OpenIdConnectHandler.ValidateTokenUsingHandlerAsync()`. The application crashed at startup due to an incompatible version of `Microsoft.IdentityModel.Tokens`, specifically related to the `TokenValidationResult` constructor signature.

Key details:
- Exception: `Method not found: 'Void TokenValidationResult..ctor(SecurityToken, TokenHandler, TokenValidationParameters, String)'`
- Affected components: OpenID Connect authentication pipeline
- NuGet versions:  
  `Microsoft.AspNetCore.Authentication.OpenIdConnect@9.0.10`  
  `Microsoft.AspNetCore.Components.WebAssembly.Server@9.0.10`
- Blazor rendering mode: WebAssembly implied by package reference

## Root Cause
A breaking change in `Microsoft.IdentityModel.Tokens` v7.x where:
- The 4-parameter `TokenValidationResult` constructor was removed
- `.NET 9.0 runtime` doesn't support legacy constructors from older lib versions
- Incorrect transitive dependency resolution pulled incompatible package versions:
    - `Microsoft.AspNetCore.Authentication.OpenIdConnect@9.0.10` depends on `Microsoft.IdentityModel.Tokens@7.x`
    - The application inadvertently referenced `Microsoft.IdentityModel.Tokens@6.x` elsewhere causing conflict
- Result: Runtime mismatch between expected and actual API surfaces

## Why This Happens in Real Systems
- **Unified package ecosystem**: .NET libraries evolve independently, causing breaking changes between major versions.
- **Transitive dependency conflicts**: Dependency resolution favors "nearest wins," allowing outdated dependencies to override newer ones.
- **Delayed failure**: Issues surface at runtime (during auth flow) rather than compile-time.
- **Version pinning**: Projects sometimes lock outdated package versions to avoid breakages elsewhere.
- **Multi-targeting complexity**: Framework upgrades (e.g., .NET Core → .NET 9) amplify dependency graph inconsistencies.

## Real-World Impact
- **Authentication outage**: Complete failure of login flows
- **Service disruption**: Application crashes on startup
- **Security risks**: Broken auth pipelines may bypass security controls
- **User trust erosion**: Inability to access critical systems
- **Extended diagnostics**: Runtime stack traces obscure the dependency conflict source

## Example or Code
**Observed Dependency Tree Conflict:**
```text
Project
├── Microsoft.AspNetCore.Authentication.OpenIdConnect@9.0.10 
│   └── Microsoft.IdentityModel.Tokens@7.0.0 [Requires new API surface]
└── ❌ OtherLib@2.0.0 
    └── Microsoft.IdentityModel.Tokens@6.22.0 [Contains legacy ctor]

Diagnostic Technique:

dotnet list package --include-transitive

Check for conflicting Microsoft.IdentityModel.Tokens versions in output.

How Senior Engineers Fix It

  1. Force dependency alignment: Add explicit package reference to correct version:
    <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.0.0" />
  2. Suppress transitives: Add top-level references to avoid transitive override:
    <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.0.0" NoWarn="NU1701" />
  3. Validation: Confirm resolution with:
    dotnet restore && dotnet build --no-incremental
  4. Version harmonization: Ensure all Microsoft.* packages target compatible versions (e.g., 7.x/8.x identities require .NET 9).
  5. Runtime verification: Test token validation flows against a stub identity provider.

Why Juniors Miss It

  • Focus on direct dependencies: Neglect transitive dependencies in solution-wide analysis.
  • Tooling gaps: Unfamiliarity with dependency tree visualization tools (dotnet list package).
  • Misleading exceptions: Runtime errors appear as code defects rather than dependency issues.
  • Assumption of compatibility: Believing Microsoft packages “just work” across major versions.
  • Limited diagnostic context: Not correlating exception signatures with dependency changelogs.
  • False attribution: Assuming the error originates in application code rather than dependency graph.