dotnet / dotnet/aspnetcore

ForwardedHeadersMiddleware has no options hot-reload, and ForwardedHeadersOptions fails to compile with the Configuration Binding source generator (CS0102/CS0111 on IPNetwork)

Open
#67,886 2 comments 0 reactions 0 assignees View on GitHub
area-middleware feature-forwarded-headers
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

## Summary

While implementing runtime (restart-free) reconfiguration of forwarded-headers trust
(e.g. adding a new custom/vanity host to `AllowedHosts` when a new tenant is added in a
multi-tenant app), I hit two related problems with `ForwardedHeaders`:

1. `ForwardedHeadersMiddleware` snapshots its options at construction and never observes
`IOptionsMonitor` changes, so options can't be hot-reloaded without an app restart.
2. `ForwardedHeadersOptions` cannot be bound via the **Configuration Binding source
generator** — enabling it produces a **build error** — which blocks the natural,
options-based way of working around problem

### Environment
- .NET 10 / ASP.NET Core 10.0
- `Microsoft.Extensions.Configuration.Binder` source generator (`true`)

---

## Problem 1 — No hot-reload of `ForwardedHeadersOptions`

`ForwardedHeadersMiddleware` reads `IOptions` **once in its
constructor** and precomputes internal state (`AllowedHosts`, `KnownNetworks`,
`KnownProxies`). Because the middleware is a singleton, changing the options at runtime via
`IOptionsMonitor.OnChange` (backed by a reloading configuration
source such as `appsettings.json` `reloadOnChange`, Azure App Configuration, etc.) has no
effect until the process is restarted.

This is inconsistent with other first-party middleware that already support live reload:
- `HostFilteringMiddleware` recomputes its allowed-hosts state on options change
(via `IOptionsMonitor` / `IOptionsChangeTokenSource`).
- `HttpLoggingMiddleware` reads `IOptionsMonitor.CurrentValue` per request.

### Ask
Make `ForwardedHeadersMiddleware` consume `IOptionsMonitor` and
recompute its cached state on change (mirroring `HostFilteringMiddleware`), so
`UseForwardedHeaders()` honors configuration reloads without a restart.

---

## Problem 2 — `ForwardedHeadersOptions` breaks the Configuration Binding source generator

With `true`, binding
`ForwardedHeadersOptions` from configuration fails to compile. The generator emits **duplicate**
helper members for the `IPNetwork` type used by `ForwardedHeadersOptions.KnownNetworks`.

### Repro
```csharp
// Boilerplate.Server.Shared.csproj
true

// any startup code
var options = new ForwardedHeadersOptions();
configuration.GetSection("ForwardedHeaders").Bind(options);

Contributor guide

Open the contributing guide

Research direction

Start by reading ForwardedHeadersMiddleware and ForwardedHeadersOptions, then compare HostFilteringMiddleware's options-change handling. Reproduce the source-generator failure with the shown EnableConfigurationBindingGenerator project and verify runtime option changes plus clean generated binding compilation. Done means both reported ForwardedHeaders problems are addressed without requiring an application restart.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.