Repository navigation
Generic host apps silently report the wrong environment (no IHostEnvironment bridge outside Sentry.AspNetCore) #5468
Description
Problem Statement
Sentry.AspNetCore bridges the .NET hosting environment to the Sentry environment automatically, via SentryAspNetCoreOptions.SetEnvironment(IWebHostEnvironment). Nothing else does.
Grepping the repo, no source file outside Sentry.AspNetCore references IHostEnvironment at all. AddSentry exists on ILoggingBuilder, ILoggerFactory, IServiceCollection, TracerProviderBuilder and IChatClient; none of them look at the host environment. So for a Worker Service, a console app, or anything else on the generic host, the only thing the SDK can resolve is SENTRY_ENVIRONMENT, because that's all SettingLocator.GetEnvironment reads.
The result is a silent misreport. Setting DOTNET_ENVIRONMENT — the documented way to tell a generic host where it's running — has no effect on Sentry, and events land in production while the host says Staging. Nothing warns, and the value looks plausible, so it tends to be discovered long after the fact.
Reproduction
Generic host, logging.AddSentry, no explicit options.Environment:
var host = Host.CreateDefaultBuilder(args)
.ConfigureLogging((context, logging) =>
{
logging.ClearProviders();
logging.AddSentry(options =>
{
options.Dsn = "...";
options.SetBeforeSend((e, _) =>
{
Console.WriteLine($"HostingEnvironment = {context.HostingEnvironment.EnvironmentName}");
Console.WriteLine($"event.Environment = {e.Environment}");
return null;
});
});
})
.Build();
host.Services.GetRequiredService<ILogger<Program>>().LogError("probe");DOTNET_ENVIRONMENT |
SENTRY_ENVIRONMENT |
HostingEnvironment |
event.Environment |
|---|---|---|---|
| (unset) | staging |
Production |
staging |
Staging |
(unset) | Staging |
production ← |
Staging |
preview |
Staging |
preview |
Row 2 is the problem. Verified against 6.4.1 on .NET 10.
Why it's easy to get wrong
The asymmetry isn't visible from the calling code. Both surfaces are configured the same way, so an app with an ASP.NET Core API and a generic-host worker reporting to the same project will have the API tag events staging while the worker tags them production — from what looks like identical setup. Cross-surface filtering then quietly excludes half the system.
It's also not obvious that Sentry.Extensions.Logging would be the wrong place to look for hosting behaviour. It's the package a worker app references, but it's a logging integration, so it has no hosting concepts — the bridge lives in a package such an app has no reason to reference.
Solution Brainstorm
A few options:
-
A generic-host integration —
Sentry.Extensions.Hosting, or anIHostBuilder.UseSentry()overload, applying the sameSetEnvironmentlogic (includingAdjustStandardEnvironmentNameCasing) thatSentry.AspNetCoredoes. Most complete, and it gives generic-host apps a natural home for other host-aware defaults later. -
Diagnostics only — if
IHostEnvironmentis resolvable and disagrees with the resolved Sentry environment, log a warning at init. Cheap, doesn't change behaviour, and would have turned a silent misreport into something discoverable. -
Docs — the .NET options docs note that the ASP.NET Core integration surfaces
staging/development, but don't say that non-ASP.NET Core apps get no host inference at all. Worth stating explicitly whatever else is done.
Context
Found while instrumenting mentaldesk/truman (ASP.NET Core API + generic-host batch worker + Svelte frontend). The JobRunner worker needed hand-written mapping to reproduce what the API gets for free.
Activity
linear-code commentedon Aug 4, 2026
NET-782
Report the correct environment per deployment
Report the correct environment per deployment
jamescrosswell commentedon Oct 11, 2026
Another instance of the same workaround: mentaldesk/truman-sentry#4, the companion repo for a blog post on wiring Sentry into a .NET + Svelte app.
The job runner is a generic-host console app using
Sentry.Extensions.Logging, so commit dec213f has to hand-roll the mappingSentry.AspNetCoredoes for the API:SENTRY_ENVIRONMENTif set, otherwiseIHostEnvironment.EnvironmentNamelower-cased for the three standard names. Without it, the API and the job runner tag events with different environments from what looks like identical config.feat!: set the Sentry environment from the host environment in every …