Host behind a reverse proxy

Forwarded headers so BaseUrl() generates correct absolute URLs.


The NuGet feed generates absolute URLs (in the service index, registration responses, and the flatcontainer) from the incoming request: Scheme, Host, and PathBase. Behind a reverse proxy, those need to reflect the public URL, not the internal one.

Enable forwarded headers

In Program.cs, before app.UseRouting():

using Microsoft.AspNetCore.HttpOverrides;

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor
                     | ForwardedHeaders.XForwardedProto
                     | ForwardedHeaders.XForwardedHost,
});

If the proxy is not on the loopback, also clear known networks/proxies:

var options = new ForwardedHeadersOptions { /* ... */ };
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
app.UseForwardedHeaders(options);

Make the proxy send the headers

  • nginx: proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host;
  • Caddy: sends forwarded headers by default
  • IIS with ASP.NET Core Module: already handled

Hosting on a sub-path

If the site lives at https://example.com/docs/, set PathBase:

app.UsePathBase("/docs");
app.UseForwardedHeaders(/* ... */);
app.UseRouting();

With that in place, BaseUrl() produces https://example.com/docs/v3, and dotnet restore can consume the feed at that URL without any client-side tricks.