---
title: "Interactive 7.x Migration Guide"
description: "Migrate from version 6.x to 7.x of the Sentry SDK for .NET with an interactive checklist."
url: https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive/
---

# Interactive 7.x Migration Guide for Blazor WebAssembly

##### Release candidate

There is no stable 7.0 release of the Sentry SDK for .NET yet. The current release candidate is `7.0.0-rc.2`. Until 7.0.0 ships, use that version wherever this guide says `7.0.0`. The rest of the .NET docs still describe 6.x until then, so where they differ from this guide, follow this guide. If you run into problems, [open an issue on GitHub](https://github.com/getsentry/sentry-dotnet/issues).

On `7.0.0-rc.2`, three things work differently from what this guide describes:

* `Logging.AddSentry()` after `ClearProviders()` doesn't add Sentry's logger providers back. Call `UseSentry` after `ClearProviders()` instead.
* `DecompressionMethods` still includes Brotli, which the next release takes out of the default. To leave it out now, set `options.DecompressionMethods = DecompressionMethods.GZip | DecompressionMethods.Deflate` where you initialize Sentry.
* An ASP.NET Core app that sends `ILogger` entries through NLog crashes with a stack overflow when `Debug` is on. In these apps, leave `Debug` off and check that the test event arrives in Sentry instead.

The release candidate's `net11.0` builds depend on the .NET 11 release candidate versions of `Microsoft.Extensions.Http`, `Microsoft.Extensions.Logging.Configuration` and `Microsoft.Extensions.Configuration.Binder`. A .NET 11 app that references 10.0.x of one of these packages directly fails to restore with error NU1605. Remove that reference, or update it to the same .NET 11 release candidate version.

Version 7 of the Sentry SDK for .NET adds support for .NET 11 and moves SDK initialization out of the logging integrations. The biggest changes are:

* **One place to initialize Sentry.** The Serilog, NLog, log4net and `Microsoft.Extensions.Logging` integrations no longer start the SDK. Call `UseSentry` or `SentrySdk.Init` first, and move the DSN and other SDK settings there.
* **`UseSentry` for generic host apps.** Worker services, Azure Functions isolated worker apps and other apps on the .NET Generic Host can now call `UseSentry` from the new `Sentry.Extensions.Hosting` package.
* **Logs.** Version 7 removes `SentryOptions.EnableLogs`. Structured logs are now enabled automatically if you add the Serilog, NLog or log4net integrations, or call `Logging.AddSentry()` after `SentrySdk.Init`, so check the volume and content of your logs after upgrading if you use any of these integrations.
* **Platforms.** Android, iOS, Mac Catalyst and MAUI apps need .NET 10 or later.
* **Defaults.** The SDK traces fewer incoming requests, and more apps report the host environment instead of `production`.

Upgrade to the latest 6.x release first, and fix its obsolete warnings. Some APIs that 7.0 removes, such as `EnableMetrics` and the iOS option `EnableAppHangTrackingV2`, are already obsolete in 6.x.

The `Sentry.OpenTelemetry` package has been obsolete since 6.12.0. Code using this integration, such as `AddSentry()` on the tracer provider builder with `options.UseOpenTelemetry()`, still compiles on 7.0, but you will get warnings. The package will not see any future improvements or bug fixes, and it will be removed in a future version. Its replacement is the OTLP exporter from `Sentry.OpenTelemetry.Exporter`, with `AddSentryOtlpExporter` and `UseOtlp`. See [OpenTelemetry (OTLP)](https://docs.sentry.io/platforms/dotnet/tracing/instrumentation/opentelemetry-otlp.md).

The compiler catches most of the changes. A few only show up at runtime or in your data. A logging integration sends nothing until you initialize Sentry. An app that calls `SentrySdk.Init` and injects `IHub` fails when the container resolves the service. The new defaults change log volume, traced requests and the reported environment. Read the behavior changes before you upgrade.

This checklist covers the 7.x migration. Some steps only apply to specific integrations, platforms or configuration options. Check off a step after you complete it or confirm that it doesn't apply to your app. This browser saves your progress.

For details about each change, see the [migration guide](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7.md).

The compiler won't catch every change. Read through the steps before upgrading, including the changes to logs, tracing and the reported environment.

## [Your Migration Steps](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#your-migration-steps)

## Check prerequisites

1 left

Runtime, language and framework versions you need before upgrading.

### Supported .NET Versions and Platforms

Action required

Android, iOS, Mac Catalyst and MAUI apps need .NET 10 or later. Version 7 adds support for .NET 11 and drops the .NET 9 targets for these platforms. Server, desktop and console apps keep the same minimums, including WPF, WinForms and WinUI apps.

| Target                                            | 6.x           | 7.x               |
| ------------------------------------------------- | ------------- | ----------------- |
| .NET                                              | .NET 8, 9, 10 | .NET 8, 9, 10, 11 |
| .NET Standard                                     | 2.0, 2.1      | 2.0, 2.1          |
| .NET Framework                                    | 4.6.2         | 4.6.2             |
| Android, iOS and Mac Catalyst targets of `Sentry` | .NET 9, 10    | .NET 10, 11       |
| `Sentry.Maui`, including its Windows target       | .NET 9, 10    | .NET 10, 11       |
| `Sentry.Maui.CommunityToolkit.Mvvm`               | .NET 9        | .NET 10 and later |

Each package keeps the .NET Standard and .NET Framework targets it had in 6.x. `Sentry` has no Windows-specific target, so WPF, WinForms and WinUI apps use its plain .NET builds, as they did in 6.x. On .NET 11, the platform minimums go up:

| Platform          | .NET 10 | .NET 11 |
| ----------------- | ------- | ------- |
| Android API level | 21      | 24      |
| Mac Catalyst      | 15.0    | 17.0    |
| iOS               | 15.0    | 15.0    |

Move each mobile or MAUI project to .NET 10 or .NET 11 before you update the Sentry packages:

```xml
<PropertyGroup>
  <TargetFrameworks
  >net10.0-android;net10.0-ios;net10.0-maccatalyst</TargetFrameworks>
</PropertyGroup>
```

An app that targets .NET 11 also needs the higher platform minimums:

```xml
<PropertyGroup>
  <SupportedOSPlatformVersion
    Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'"
  >24.0</SupportedOSPlatformVersion>
  <SupportedOSPlatformVersion
    Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'"
  >17.0</SupportedOSPlatformVersion>
</PropertyGroup>
```

If a project still targets `net9.0-android`, `net9.0-ios` or `net9.0-maccatalyst`, NuGet gives it the plain `net9.0` build of `Sentry` 7. That build has no native SDK, so the app loses native crash reporting. Stay on 6.x until you move the app to .NET 10.

A .NET 9 MAUI project can't use `Sentry.Maui` 7 at all. The package has no .NET 9 target, so NuGet fails the restore with error NU1202.

## Update packages

1 left

Installs, removals and moved entry points.

### Update All Sentry Packages Together

Action required

Update every Sentry package in the solution to the same 7.x version. A 6.x integration package left next to `Sentry` 7 breaks at runtime with `MissingMethodException`, because it calls members that 7.0 removes.

`Sentry.Extensions.Logging` 6.12.1 throws when the app builds its logger factory, and `Sentry.Serilog` 6.12.1 throws when the app calls `WriteTo.Sentry()` without arguments. Set up in other ways, `Sentry.Serilog` and `Sentry.NLog` 6.12.1 fail on every entry they write instead. Serilog and NLog swallow that exception, so the app keeps running and sends nothing to Sentry.

```xml
<ItemGroup>
  <PackageReference Include="Sentry.AspNetCore" Version="7.0.0" />
  <PackageReference Include="Sentry.Serilog" Version="7.0.0" />
</ItemGroup>
```

If the solution uses central package management, update the versions in `Directory.Packages.props` instead.

Worker services and other generic host apps that started Sentry with `Logging.AddSentry` need the new `Sentry.Extensions.Hosting` package instead of `Sentry.Extensions.Logging`. `Sentry.Extensions.Hosting` brings in `Sentry.Extensions.Logging`, so remove the direct reference. See [Generic Host Apps Call UseSentry](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#generic-host-apps-call-usesentry).

```shell
dotnet add package Sentry.Extensions.Hosting
```

## Make required code changes

13 left

Options, APIs and config that changed and need your attention.

### Logging Integrations No Longer Initialize Sentry

Action required

The Serilog sink, the NLog target, the log4net appender and `Logging.AddSentry()` no longer start the SDK. Initialize Sentry once at startup, before the logging framework, and move the DSN and every other SDK setting there.

Initialize Sentry with the call that matches your app:

| App                                                                                           | Initialize Sentry with                                                                                                                                                                                                                                        |
| --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ASP.NET Core                                                                                  | `UseSentry` from `Sentry.AspNetCore`                                                                                                                                                                                                                          |
| MAUI                                                                                          | `UseSentry` from `Sentry.Maui`                                                                                                                                                                                                                                |
| Blazor WebAssembly                                                                            | `UseSentry` from `Sentry.AspNetCore.Blazor.WebAssembly`                                                                                                                                                                                                       |
| Worker services, Azure Functions isolated worker apps and other apps on the .NET Generic Host | `UseSentry` from `Sentry.Extensions.Hosting`                                                                                                                                                                                                                  |
| Console apps that build their own `ServiceCollection` without a host                          | `SentrySdk.Init`, then `Logging.AddSentry()`. If the app injects `IHub`, see [IHub Is Registered Only by UseSentry](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#ihub-is-registered-only-by-usesentry) |
| Other console apps, ASP.NET on .NET Framework and any other app                               | `SentrySdk.Init`                                                                                                                                                                                                                                              |

`UseSentry` reads its settings from the `Sentry` section of `appsettings.json`. `SentrySdk.Init` only uses the options you set in code and environment variables such as `SENTRY_DSN`.

`UseSentry` also adds Sentry's own `ILogger` integration. If your app sends `ILogger` entries through Serilog, NLog or log4net as well, Sentry receives each entry twice unless only one of them sends it:

* **Serilog.** Add Serilog with `builder.Services.AddSerilog(...)` from `Serilog.Extensions.Hosting`, or with `builder.Host.UseSerilog(...)`. Both replace the app's `ILogger` factory, so each entry reaches Sentry once, through the sink. Don't use `builder.Logging.AddSerilog()` or `writeToProviders: true`.
* **NLog.** Set `ReplaceLoggerFactory = true` when you add NLog, for example with `builder.Logging.AddNLog(new NLogProviderOptions { ReplaceLoggerFactory = true })`. `UseNLog` in ASP.NET Core takes the same option.
* **log4net.** `AddLog4Net()` can't replace the factory. Set `MinimumEventLevel` and `MinimumBreadcrumbLevel` to `LogLevel.None` on the options of `UseSentry`, and leave `EnableLogs` off, so each entry reaches Sentry once, through the appender.

The [Serilog](https://docs.sentry.io/platforms/dotnet/guides/serilog.md#apps-that-call-usesentry), [NLog](https://docs.sentry.io/platforms/dotnet/guides/nlog.md#apps-that-call-usesentry) and [log4net](https://docs.sentry.io/platforms/dotnet/guides/log4net.md#apps-that-call-usesentry) guides show the full setup.

A logging integration sends nothing until you initialize Sentry. SDK settings left on the integration fail in different ways:

* `Logging.AddSentry(o => o.Dsn = ...)`, the Serilog `WriteTo.Sentry(dsn)` overload and the NLog `AddSentry(dsn)` overloads fail to compile with error CS0619, to make it clear that these integrations no longer initialize the SDK. The error message explains what to change.
* Other SDK settings in code, such as `TracesSampleRate` on `SentryLoggingOptions` or `Environment` on the Serilog and NLog options, fail to compile with error CS1061.
* `Dsn` or any other SDK setting under `Logging:Sentry` in configuration throws `NotSupportedException` at startup.
* A `dsn` argument in Serilog's JSON configuration fails when Serilog reads the configuration, with a `TargetInvocationException` whose inner `NotSupportedException` explains the change. Serilog ignores other SDK arguments, such as `environment`, without a message.
* The NLog target writes one message to standard error for `dsn`. NLog ignores `environment`, `release` and the other SDK settings without a message.
* The log4net appender writes an error to standard error for `Dsn` and for `Environment`.

The changes for each integration are in these sections:

* [Generic Host Apps Call UseSentry](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#generic-host-apps-call-usesentry)
* [Logging Options Only Set Log Levels](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#logging-options-only-set-log-levels)
* [Move SDK Settings Out of the Serilog Sink](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#move-sdk-settings-out-of-the-serilog-sink)
* [Move SDK Settings Out of the NLog Target](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#move-sdk-settings-out-of-the-nlog-target)
* [Move SDK Settings Out of the log4net Appender](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#move-sdk-settings-out-of-the-log4net-appender)

After the upgrade, run the app once and confirm that Sentry starts. A build alone doesn't catch a missing initialization. An NLog or log4net app with only the package versions bumped builds, runs and sends nothing. Set `Debug` to `true` where you initialize Sentry, look for `Initializing Hub for Dsn` in the console output, and capture a test event:

```csharp
using var sentry = SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.Debug = true;
});

SentrySdk.CaptureMessage("Sentry 7 is set up");
```

Turn `Debug` off again once the event arrives.

### Generic Host Apps Call UseSentry

Action required

Worker services, Azure Functions isolated worker apps, Windows services and console apps on `Host.CreateApplicationBuilder` often started Sentry with `Logging.AddSentry`. Install `Sentry.Extensions.Hosting` and call `UseSentry` on the host builder instead.

```shell
dotnet add package Sentry.Extensions.Hosting
```

`Sentry.Extensions.Hosting` brings in `Sentry.Extensions.Logging`, so remove the app's direct `Sentry.Extensions.Logging` reference.

In 6.x, `Logging.AddSentry()` started Sentry with the settings under `Logging:Sentry`:

```csharp
var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddSentry();
builder.Services.AddHostedService<Worker>();
builder.Build().Run();
```

*Other available variations of the above snippet: json*

In 7.x, `UseSentry()` starts Sentry with the settings in the `Sentry` section and adds the `ILogger` integration. The log levels stay under `Logging:Sentry`:

```csharp
var builder = Host.CreateApplicationBuilder(args);
builder.UseSentry();
builder.Services.AddHostedService<Worker>();
builder.Build().Run();
```

*Other available variations of the above snippet: json*

If the app set the options in code, move them from `Logging.AddSentry` to `UseSentry`. In 6.x, the code looked like this:

```csharp
var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddSentry(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.TracesSampleRate = 1.0;
});
builder.Services.AddHostedService<Worker>();
builder.Build().Run();
```

In 7.x, pass the same options to `UseSentry`:

```csharp
var builder = Host.CreateApplicationBuilder(args);
builder.UseSentry(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.TracesSampleRate = 1.0;
});
builder.Services.AddHostedService<Worker>();
builder.Build().Run();
```

`UseSentry` also registers `IHub` for dependency injection and sets the environment from the host environment. It works on `IHostApplicationBuilder` types such as `Host.CreateApplicationBuilder` on .NET 8 and later. It also works on `IHostBuilder` types such as `Host.CreateDefaultBuilder` on every target, including .NET Framework.

If the app calls `builder.Logging.ClearProviders()`, call `UseSentry` after it. `ClearProviders` removes every logger provider registered before it, including Sentry's, and the app then sends no errors from `ILogger`. If the app has to clear providers after `UseSentry`, call `builder.Logging.AddSentry()` after `ClearProviders` to add Sentry's providers back. Skip that if Serilog, NLog or log4net already sends the app's `ILogger` entries to Sentry, because each entry would then arrive twice.

A helper that takes any `IHostApplicationBuilder` and runs in an ASP.NET Core app, such as the `AddServiceDefaults` method of .NET Aspire, needs a different call. See [Call UseSentry on WebApplicationBuilder](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#call-usesentry-on-webapplicationbuilder).

Like ASP.NET Core, `UseSentry` sends `ILogger` entries as logs only when you set `EnableLogs`. See [EnableLogs Is Removed from SentryOptions](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#enablelogs-is-removed-from-sentryoptions).

### Logging Options Only Set Log Levels

Action required

`SentryLoggingOptions` and the `Logging:Sentry` configuration section now only set log levels. `SentryLoggingOptions` no longer derives from `SentryOptions`, so SDK settings passed to `Logging.AddSentry` fail to compile. Move them to where you initialize Sentry.

In 6.x, `Logging.AddSentry` accepted every SDK option:

```csharp
using Microsoft.Extensions.Logging;

using var loggerFactory = LoggerFactory.Create(logging =>
    logging.AddSentry(options =>
    {
        options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
        options.MinimumEventLevel = LogLevel.Error;
    }));
```

In 7.x, initialize Sentry first and keep only the log levels on the logging integration:

```csharp
using Microsoft.Extensions.Logging;

using var sentry = SentrySdk.Init(options => options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>");

using var loggerFactory = LoggerFactory.Create(logging =>
    logging.AddSentry(options => options.MinimumEventLevel = LogLevel.Error));
```

In configuration, `Logging:Sentry` accepts only `MinimumEventLevel`, `MinimumBreadcrumbLevel` and `LogLevel`. Any other key throws `NotSupportedException` at startup. This includes ASP.NET Core, Blazor WebAssembly and generic host apps, because `UseSentry` reads the log levels from `Logging:Sentry`. In 6.x, the SDK settings lived under `Logging:Sentry`:

```json
{
  "Logging": {
    "Sentry": {
      "Dsn": "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
      "SendDefaultPii": true,
      "MinimumEventLevel": "Error"
    }
  }
}
```

In 7.x, move the SDK settings to the `Sentry` section, which `UseSentry` reads:

```json
{
  "Logging": {
    "Sentry": {
      "MinimumEventLevel": "Error"
    }
  },
  "Sentry": {
    "Dsn": "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
    "SendDefaultPii": true
  }
}
```

`SentrySdk.Init` doesn't read the `Sentry` section. If the app initializes Sentry with `SentrySdk.Init`, set the options in code, or switch to `UseSentry` if the app has a host.

Other members moved with this change:

* `ConfigureScope` moved from `SentryLoggingOptions` to the options of `UseSentry`. With `SentrySdk.Init`, call `SentrySdk.ConfigureScope` after initializing.
* `InitializeSdk` fails to compile. Remove it, since no logging integration initializes the SDK anymore.
* The options of `UseSentry`, such as `SentryAspNetCoreOptions` and `SentryMauiOptions`, now derive from the new `SentryHostOptions` class instead of `SentryLoggingOptions`. Code that takes these options as `SentryLoggingOptions` needs to take `SentryHostOptions`.
* `AddSentry<TOptions>()` on `IServiceCollection` now requires `TOptions` to derive from `SentryHostOptions`.

### IHub Is Registered Only by UseSentry

Action required

`Logging.AddSentry()` no longer registers `IHub`, `ISentryClient` or `Func<IHub>` for dependency injection. If the app initializes Sentry with `SentrySdk.Init` and injects one of them, the service container throws `InvalidOperationException` when it resolves the service.

The compiler can't catch this. The app fails at runtime with an error like `Unable to resolve service for type 'Sentry.IHub'`.

If the app has a host, use `UseSentry`, which registers all three. Otherwise, register `HubAdapter.Instance` for each one. `HubAdapter` is in the `Sentry.Extensibility` namespace.

In 6.x, `Logging.AddSentry` registered them:

```csharp
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

var services = new ServiceCollection();
services.AddLogging(logging =>
    logging.AddSentry(options => options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>"));
```

In 7.x, if you are resolving any of these services for use in your application, you will need to register them yourself:

```csharp
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Sentry.Extensibility;

using var sentry = SentrySdk.Init(options => options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>");

var services = new ServiceCollection();
services.AddLogging(logging => logging.AddSentry());
services.AddSingleton<IHub>(HubAdapter.Instance);
services.AddSingleton<ISentryClient>(HubAdapter.Instance);
services.AddSingleton<Func<IHub>>(() => HubAdapter.Instance);
```

### Remove Redundant Logging.AddSentry Calls

Action required

In an app that calls `UseSentry`, `Logging.AddSentry()` now does nothing, and options passed to it in code no longer apply. Move those options to `UseSentry` and remove the call.

The exception is an app that calls `ClearProviders()` after `UseSentry`, which also removes Sentry's logger providers. Keep `Logging.AddSentry()` there to add them back. It uses the options of `UseSentry`, not the ones passed to it. Leave it out if Serilog, NLog or log4net already sends the app's `ILogger` entries to Sentry, because each entry would then arrive twice.

In 6.x, an app with both calls captured each error, breadcrumb and log twice. In 7.x, the `ILogger` integration that `UseSentry` adds captures them once, with the options of `UseSentry`. With `Debug` on, the SDK logs a warning about the redundant call.

In 6.x, the app passed the logging options to `Logging.AddSentry`:

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseSentry(options => options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>");
builder.Logging.AddSentry(options => options.MinimumBreadcrumbLevel = LogLevel.Debug);
```

In 7.x, set them on the options of `UseSentry`:

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.UseSentry(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.MinimumBreadcrumbLevel = LogLevel.Debug;
});
```

Blazor WebAssembly apps often called `Logging.AddSentry` with `InitializeSdk = false`. That line now fails to compile with error CS0619. In 6.x, the setup looked like this:

```csharp
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.UseSentry(options => options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>");
builder.Logging.AddSentry(options => options.InitializeSdk = false);
```

In 7.x, remove the `Logging.AddSentry` line:

```csharp
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.UseSentry(options => options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>");
```

The log levels under `Logging:Sentry` keep working, because `UseSentry` reads that section too.

### Move SDK Settings Out of the Serilog Sink

Action required

The Serilog sink no longer initializes Sentry, and `SentrySerilogOptions` no longer derives from `SentryOptions`. Initialize Sentry first, call `UseSerilog()` on its options, and keep only the sink's own settings in `WriteTo.Sentry`.

SDK settings on the sink options, such as `Dsn`, `Environment`, `Release`, `AttachStacktrace` or `InitializeSdk`, fail to compile with error CS1061. In 6.x, the sink took them all:

```csharp
using Serilog;
using Serilog.Events;

Log.Logger = new LoggerConfiguration()
    .WriteTo.Sentry(options =>
    {
        options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
        options.Environment = "staging";
        options.MinimumEventLevel = LogEventLevel.Error;
        options.MinimumBreadcrumbLevel = LogEventLevel.Information;
    })
    .CreateLogger();
```

In 7.x, move the SDK settings to `SentrySdk.Init`. The sink keeps only its own settings, which are `MinimumEventLevel`, `MinimumBreadcrumbLevel`, `RestrictedToMinimumLevel`, `LevelSwitch`, `FormatProvider` and `TextFormatter`:

```csharp
using Sentry.Serilog;
using Serilog;
using Serilog.Events;

using var sentry = SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.Environment = "staging";
    options.UseSerilog();
});

Log.Logger = new LoggerConfiguration()
    .WriteTo.Sentry(options =>
    {
        options.MinimumEventLevel = LogEventLevel.Error;
        options.MinimumBreadcrumbLevel = LogEventLevel.Information;
    })
    .CreateLogger();
```

In ASP.NET Core and other apps that call `UseSentry`, call `options.UseSerilog()` in the `UseSentry` options instead.

`UseSerilog()` replaces `ApplySerilogScopeToEvents()`. It adds properties from Serilog's `LogContext` to Sentry events. The sink also does this the first time it writes, so the call only matters for events captured before then. `UseSerilog()` is in the `Sentry.Serilog` namespace and returns `void`, so it can't be chained like `ApplySerilogScopeToEvents()`.

If you configure the sink in `appsettings.json`, remove `dsn` and every other SDK setting from its `Args`. A `dsn` argument fails when Serilog reads the configuration, with a `TargetInvocationException` whose inner `NotSupportedException` explains the change. Serilog ignores other SDK arguments, such as `environment`, without a message. In 6.x, the sink arguments included the SDK settings:

```json
{
  "Serilog": {
    "WriteTo": [
      {
        "Name": "Sentry",
        "Args": {
          "dsn": "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
          "environment": "staging",
          "minimumEventLevel": "Error"
        }
      }
    ]
  }
}
```

In 7.x, keep only the sink settings, and initialize Sentry in code or with `UseSentry`:

```json
{
  "Serilog": {
    "WriteTo": [
      {
        "Name": "Sentry",
        "Args": {
          "minimumEventLevel": "Error"
        }
      }
    ]
  }
}
```

The `enableLogs` argument is gone too, because the sink now sends logs once you add it. See [Logging Integrations Send Logs](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#logging-integrations-send-logs). `Log.CloseAndFlush()` no longer closes Sentry. See [Logging Frameworks No Longer Close Sentry](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#logging-frameworks-no-longer-close-sentry).

### Move SDK Settings Out of the NLog Target

Action required

The NLog target no longer initializes Sentry. Initialize Sentry first, and remove every SDK setting from the target, including the ones NLog doesn't report. A target that keeps `environment` or `release` stops sending them without a warning.

The target writes one message to standard error for `dsn`, or for `initializeSdk` set to `true`. NLog ignores the other settings below without a message. Move each one to the options of `SentrySdk.Init` or `UseSentry`:

| NLog target setting in 6.x                                                           | 7.x                                             |
| ------------------------------------------------------------------------------------ | ----------------------------------------------- |
| `dsn`                                                                                | `options.Dsn`                                   |
| `environment`                                                                        | `options.Environment`                           |
| `release`                                                                            | `options.Release`                               |
| `flushTimeoutSeconds`                                                                | `options.FlushTimeout`                          |
| `shutdownTimeoutSeconds`                                                             | `options.ShutdownTimeout`                       |
| `initializeSdk`                                                                      | Remove it                                       |
| SDK settings in `<options>`, such as `sendDefaultPii`, `attachStacktrace` or `debug` | The `SentryOptions` property with the same name |

NLog layouts in these settings don't carry over, because `SentryOptions` takes plain values. A release written as a layout, such as `${assembly-version:cached=true:type=File}`, needs a value you set in code. If you leave `Release` unset, the SDK uses the entry assembly's name and version, such as `MyApp@1.2.3`, which differs from what the layout produced.

Target settings such as `minimumEventLevel`, `minimumBreadcrumbLevel`, `layout`, `breadcrumbLayout`, `<tag>` and `includeEventDataOnBreadcrumbs` keep working. In 6.x, the target carried the SDK settings:

```xml
<nlog
  xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
  <extensions>
    <add assembly="Sentry.NLog" />
  </extensions>
  <targets>
    <target
      xsi:type="Sentry"
      name="sentry"
      dsn="https://<key>@o<orgId>.ingest.sentry.io/<projectId>"
      environment="staging"
      release="my-app@1.2.3"
      minimumBreadcrumbLevel="Debug"
      minimumEventLevel="Error"
    >
      <options sendDefaultPii="true" />
    </target>
  </targets>
  <rules>
    <logger name="*" writeTo="sentry" />
  </rules>
</nlog>
```

In 7.x, the target keeps only its own settings:

```xml
<nlog
  xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
  <extensions>
    <add assembly="Sentry.NLog" />
  </extensions>
  <targets>
    <target
      xsi:type="Sentry"
      name="sentry"
      minimumBreadcrumbLevel="Debug"
      minimumEventLevel="Error"
    />
  </targets>
  <rules>
    <logger name="*" writeTo="sentry" />
  </rules>
</nlog>
```

Initialize Sentry with the SDK settings before NLog writes its first entry:

```csharp
using NLog;

using var sentry = SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.Environment = "staging";
    options.Release = "my-app@1.2.3";
    options.SendDefaultPii = true;
});

var logger = LogManager.GetCurrentClassLogger();
```

If you configure the target in code, `SentryNLogOptions` no longer derives from `SentryOptions`, so SDK settings fail to compile with error CS1061. In 6.x, `AddSentry` took them:

```csharp
using NLog;
using NLog.Config;

LogManager.Configuration = new LoggingConfiguration()
    .AddSentry(options =>
    {
        options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
        options.Environment = "staging";
        options.MinimumEventLevel = LogLevel.Error;
    });
```

In 7.x, move them to `SentrySdk.Init`:

```csharp
using NLog;
using NLog.Config;

using var sentry = SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.Environment = "staging";
});

LogManager.Configuration = new LoggingConfiguration()
    .AddSentry(options => options.MinimumEventLevel = LogLevel.Error);
```

NLog's `enableLogs` setting is obsolete and has no effect, because the target now sends logs once you add it. See [Logging Integrations Send Logs](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#logging-integrations-send-logs). The target now flushes with `SentryOptions.FlushTimeout`, which defaults to 2 seconds instead of 15. See [Logging Frameworks No Longer Close Sentry](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#logging-frameworks-no-longer-close-sentry).

### Move SDK Settings Out of the log4net Appender

Action required

The log4net appender no longer initializes Sentry, and version 7 removes its `Environment` setting. Initialize Sentry first, and remove `Dsn` and `Environment` from the appender. log4net writes an error to standard error for each of them.

In 6.x, the appender initialized Sentry from its configuration:

```xml
<appender
  name="SentryAppender"
  type="Sentry.Log4Net.SentryAppender, Sentry.Log4Net"
>
  <Dsn value="https://<key>@o<orgId>.ingest.sentry.io/<projectId>" />
  <Environment value="staging" />
  <SendIdentity value="true" />
  <threshold value="INFO" />
</appender>
```

In 7.x, the appender keeps `SendIdentity`, `MinimumEventLevel` and the log4net settings such as `threshold`:

```xml
<appender
  name="SentryAppender"
  type="Sentry.Log4Net.SentryAppender, Sentry.Log4Net"
>
  <SendIdentity value="true" />
  <threshold value="INFO" />
</appender>
```

Initialize Sentry in code before log4net writes its first entry:

```csharp
using var sentry = SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.Environment = "staging";
});

log4net.Config.XmlConfigurator.Configure();
```

In an ASP.NET app on .NET Framework, call `SentrySdk.Init` in `Application_Start`, as the ASP.NET integration already requires. The appender now sends logs once you add it. See [Logging Integrations Send Logs](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#logging-integrations-send-logs).

### EnableLogs Is Removed from SentryOptions

Action required

Version 7 removes `EnableLogs` from `SentryOptions`, the core options of the SDK, so setting it in `SentrySdk.Init` fails to compile with error CS1061. Remove the line.

Whether logs are on now depends on how your app writes them:

* **Logging integrations.** If you add the Serilog, NLog or log4net integration, or call `Logging.AddSentry()` after `SentrySdk.Init`, logs are on by default. Your logging framework's configuration, such as its minimum level, controls which entries they send. See [Logging Integrations Send Logs](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#logging-integrations-send-logs).
* **Host integrations.** In ASP.NET Core, MAUI, Blazor WebAssembly and generic host apps, `UseSentry` adds an `ILogger` integration. It sends errors and breadcrumbs, but its logs are off by default. To turn them on, set `EnableLogs = true` on the options of `UseSentry`. `EnableLogs` doesn't affect a Serilog, NLog or log4net integration in the same app.
* **`SentrySdk.Logger`.** It sends logs in every app and needs no option.

In 6.x, `SentrySdk.Init` turned logs on:

```csharp
SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.EnableLogs = true;
});
```

In 7.x, remove `EnableLogs`:

```csharp
SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
});
```

In apps that call `UseSentry`, keep `EnableLogs` on its options to send `ILogger` entries as logs. You can also set it in the `Sentry` section of `appsettings.json`:

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.UseSentry(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.EnableLogs = true;
});
```

A generic host app that set `EnableLogs` on `Logging.AddSentry` in 6.x sets it on `UseSentry` now.

The Serilog sink no longer takes an `enableLogs` argument. NLog's `enableLogs` setting no longer turns logs off, and setting it to `false` writes a warning to standard error. To drop logs and keep errors and breadcrumbs, use `SetBeforeSendLog`, as shown in [Logging Integrations Send Logs](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#logging-integrations-send-logs).

### EnableMetrics Is Removed

Action required

Version 7 removes `SentryOptions.EnableMetrics`, so setting it fails to compile with error CS1061. The option has been obsolete and ignored since 6.10.0, because metrics are always on. To drop metrics, return `null` from `SetBeforeSendMetric`.

In 6.x, the obsolete option compiled but had no effect:

```csharp
SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.EnableMetrics = false;
});
```

In 7.x, drop metrics in the callback:

```csharp
SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.SetBeforeSendMetric(_ => null);
});
```

The SDK ignores an `EnableMetrics` key in the `Sentry` section of `appsettings.json`. Remove it.

### Release and Distribution Are Set on Options

Action required

Version 7 removes `Scope.Release`, `Scope.Distribution` and `SentryOptions.ApplyDefaultTags`. `Release` and `Distribution` also move from `IEventLike` to `ITransactionData`. Set the release and distribution on `SentryOptions` instead.

In 6.x, the scope could set the release:

```csharp
SentrySdk.Init(options => options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>");
SentrySdk.ConfigureScope(scope =>
{
    scope.Release = "my-app@1.2.3";
    scope.Distribution = "42";
});
```

In 7.x, set both on the options:

```csharp
SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.Release = "my-app@1.2.3";
    options.Distribution = "42";
});
```

Events, transactions and check-ins keep their own `Release` property. To change the release of a single event, set `Release` on the event in `SetBeforeSend`. Code that reads `Release` or `Distribution` through an `IEventLike` variable needs a `SentryEvent` or `ITransactionData` variable instead.

`DefaultTags` are still applied to events and transactions. Remove calls to `options.ApplyDefaultTags`.

### The OpenTelemetry Exporter No Longer Sets a Propagator

Action required

`AddSentryOtlpExporter` and `UseOtlp` no longer set `SentryPropagator` as OpenTelemetry's default propagator, and they no longer take a `defaultTextMapPropagator` parameter. OpenTelemetry's default W3C propagator applies instead, so `sentry-trace` headers stop going out unless you set the propagator yourself.

A call that passes `defaultTextMapPropagator` fails to compile with error CS1739. In 6.x, the exporter set the propagator:

```csharp
using OpenTelemetry;
using OpenTelemetry.Trace;
using Sentry.OpenTelemetry;

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddSource("MyApp")
    .AddSentryOtlpExporter("https://<key>@o<orgId>.ingest.sentry.io/<projectId>", defaultTextMapPropagator: new SentryPropagator())
    .Build();
```

In 7.x, set the propagator with the OpenTelemetry SDK. To keep sending and reading `sentry-trace` headers, add `SentryPropagator` next to the W3C propagator:

```csharp
using OpenTelemetry;
using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Trace;
using Sentry.OpenTelemetry;

Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[]
{
    new TraceContextPropagator(),
    new SentryPropagator(),
}));

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddSource("MyApp")
    .AddSentryOtlpExporter("https://<key>@o<orgId>.ingest.sentry.io/<projectId>")
    .Build();
```

Services that only talk to other OpenTelemetry services don't need `SentryPropagator`, because the W3C `traceparent` header connects their traces. See [OpenTelemetry (OTLP)](https://docs.sentry.io/platforms/dotnet/tracing/instrumentation/opentelemetry-otlp.md) for details.

### Other Removed and Internal APIs

Action required

Version 7 removes a few APIs that most apps don't use, makes others internal and reorders some parameters. Update any code that uses them:

| API                                                                                            | Migration                                                                                               |
| ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `Envelope.FromEvent`, `Envelope.FromFeedback`, `Envelope.FromTransaction`                      | The `IDiagnosticLogger` parameter moves to the end. Reorder the arguments or pass them by name.         |
| `options.Native.EnableAppHangTrackingV2` on iOS and Mac Catalyst                               | Use `options.Native.EnableAppHangTracking`. App hang tracking V2 is already the default.                |
| `options.Native.AddInAppExclude(string)` on iOS and Mac Catalyst                               | Remove the call. It had no effect.                                                                      |
| `SentryOptions.ScopeObserver`, `SentryOptions.EnableScopeSync`, `SentryOptions.CrashedLastRun` | These are internal now, because only the SDK's native integrations set them. Remove references to them. |

The SDK ignores an `EnableScopeSync` key in the `Sentry` section of `appsettings.json`.

The `Envelope` factory methods only matter if you build envelopes yourself, for example in a custom transport. In 6.x, the logger came second:

```csharp
using Sentry.Extensibility;
using Sentry.Protocol.Envelopes;

static Envelope CreateEnvelope(SentryEvent @event, IDiagnosticLogger logger,
    IReadOnlyCollection<SentryAttachment> attachments, SessionUpdate sessionUpdate)
    => Envelope.FromEvent(@event, logger, attachments, sessionUpdate);
```

In 7.x, the logger comes last:

```csharp
using Sentry.Extensibility;
using Sentry.Protocol.Envelopes;

static Envelope CreateEnvelope(SentryEvent @event, IDiagnosticLogger logger,
    IReadOnlyCollection<SentryAttachment> attachments, SessionUpdate sessionUpdate)
    => Envelope.FromEvent(@event, attachments, sessionUpdate, logger);
```

On iOS and Mac Catalyst, the 6.x app hang option looked like this:

```csharp
SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.Native.EnableAppHangTrackingV2 = true;
});
```

In 7.x, use the main option:

```csharp
SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.Native.EnableAppHangTracking = true;
});
```

The SDK no longer reads the breadcrumb level `"critical"` as `Fatal`. Only envelopes that a 5.x app cached on disk and never sent used that level.

## Verify behavior changes

7 left

Check dashboards and alerts.

### Logging Integrations Send Logs

Behavior change

The Serilog sink, the NLog target, the log4net appender and `Logging.AddSentry()` after `SentrySdk.Init` send every entry they receive to Sentry as a log. In 6.x, they sent logs only with `EnableLogs` on, so an upgraded app can send many more logs.

Adding one of these integrations is now the opt-in for its logs, in every kind of app. `EnableLogs` on the options of `UseSentry` doesn't change this. See [EnableLogs Is Removed from SentryOptions](https://docs.sentry.io/platforms/dotnet/guides/blazor-webassembly/migration/v6-to-v7/interactive.md#enablelogs-is-removed-from-sentryoptions).

Each integration sends the entries its logging framework passes to it:

* The Serilog sink gets entries at the logger's minimum level, which is `Information` unless you change it.
* The NLog target gets the levels of the rules that write to it.
* The log4net appender gets entries at its `threshold`.
* `Logging.AddSentry()` gets the levels from the `Logging` configuration, which default to `Information`.

Logs carry whatever the app writes at those levels. Debug and Information lines can hold personal data, such as customer email addresses, that 6.x didn't send to Sentry as logs. Check what those levels contain before you upgrade.

To keep only warnings and more severe logs, filter on the level in `SetBeforeSendLog`:

```csharp
SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.SetBeforeSendLog(log => log.Level >= SentryLogLevel.Warning ? log : null);
});
```

To drop every log and keep sending errors and breadcrumbs, return `null`:

```csharp
SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.SetBeforeSendLog(_ => null);
});
```

In apps that call `UseSentry`, set the same callback on its options. The callback applies to every log, including logs from `SentrySdk.Logger` and from the `ILogger` integration.

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.UseSentry(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.SetBeforeSendLog(_ => null);
});
```

See [Logs](https://docs.sentry.io/platforms/dotnet/logs.md) for more about filtering logs.

### Some Requests Are No Longer Traced

Behavior change

ASP.NET Core and ASP.NET apps no longer send a transaction for an incoming request that ends in 301, 305 to 399, or 401 to 404. `TraceIgnoreStatusCodes` now contains these codes by default, so dashboards and alerts that count these transactions see fewer of them.

The default leaves out 302 and 303, because ASP.NET Core apps use them to redirect after a successful form post. The setting only affects the SDK's own `http.server` transactions, including the ones the `Sentry.OpenTelemetry` span processor creates. The SDK still traces outgoing `HttpClient` requests whatever their status code. OpenTelemetry spans that the OTLP exporter sends don't go through this setting, so a 404 still shows up there.

To trace every request again, clear the list:

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.UseSentry(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.TracesSampleRate = 1.0;
    options.TraceIgnoreStatusCodes.Clear();
});
```

To ignore only some status codes, replace the list:

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.UseSentry(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.TracesSampleRate = 1.0;
    options.TraceIgnoreStatusCodes = [404, (500, 599)];
});
```

You can also replace the list in `appsettings.json`:

```json
{
  "Sentry": {
    "TraceIgnoreStatusCodes": [404]
  }
}
```

An empty array in configuration doesn't clear the list, because configuration binds `[]` as a missing value. To trace every request from configuration alone, set `[0]`. Configuration can't express ranges.

### More Apps Report the Host Environment

Behavior change

More apps that don't set `Environment` now report the .NET host environment, such as `development` or `staging`. In 6.x, these apps reported `production`, or `debug` with a debugger attached.

The change affects these apps:

* Blazor WebAssembly apps.
* Google Cloud Functions.
* ASP.NET Core apps that call the `UseSentry` overload that takes an `ISentryBuilder` callback, as gRPC apps do.
* Generic host apps that move from `Logging.AddSentry` to `UseSentry` from `Sentry.Extensions.Hosting`.

The SDK lowercases the standard names `Production`, `Staging` and `Development`, and keeps custom names as they are. An `Environment` set in code or in the `Sentry` section of `appsettings.json` still wins, followed by the `SENTRY_ENVIRONMENT` environment variable.

Update alerts, saved searches and dashboards that filter on the old value. To keep reporting `production`, set the environment explicitly:

```csharp
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.UseSentry(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.Environment = "production";
});
```

### SDK Name, Release and Scope Environment

Behavior change

The SDK now resolves the SDK name, release and environment once, when Sentry starts, and applies them to every kind of telemetry the same way. Check searches, alerts and dashboards that depend on these values.

Events, transactions, logs and metrics report the SDK name of the integration that initialized Sentry, such as `sentry.dotnet.aspnetcore`, `sentry.dotnet.extensions.hosting` or `sentry.dotnet`. Events captured by Serilog, NLog, log4net or `ILogger` no longer report `sentry.dotnet.serilog`, `sentry.dotnet.nlog`, `sentry.dotnet.log4net` or `sentry.dotnet.extensions.logging`. Blazor WebAssembly apps now report `sentry.dotnet.aspnetcore.blazor.webassembly`. Update searches and alerts that filter on `sdk.name`.

On Android, iOS and Mac Catalyst, a `SENTRY_RELEASE` environment variable now takes precedence over the release that the SDK derives from the app package.

An environment set on the scope now also applies to logs, metrics, sessions, check-ins and trace propagation, as it already did to events. Set `Scope.Environment` to `null` to go back to the environment from the options:

```csharp
SentrySdk.ConfigureScope(scope => scope.Environment = "canary");

// Later, to report the environment from the options again:
SentrySdk.ConfigureScope(scope => scope.Environment = null);
```

### Logging Frameworks No Longer Close Sentry

Behavior change

`Log.CloseAndFlush()` in Serilog, `LogManager.Shutdown()` in NLog and shutting down the log4net repository no longer close Sentry. In 6.x, they closed Sentry when the logging integration had initialized it. Now the code that calls `SentrySdk.Init` or `UseSentry` owns the SDK.

The SDK still flushes when the process exits. In a short-lived app, dispose the object that `SentrySdk.Init` returns, or call `SentrySdk.Flush()`, before the app exits:

```csharp
using Serilog;

using var sentry = SentrySdk.Init(options => options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>");

Log.Logger = new LoggerConfiguration()
    .WriteTo.Sentry()
    .CreateLogger();

try
{
    Log.Information("Running the job");
}
finally
{
    Log.CloseAndFlush();
}
```

The NLog target flushes Sentry when NLog flushes. It now waits up to `SentryOptions.FlushTimeout`, which defaults to 2 seconds, instead of the 15 seconds it used to wait. To keep 15 seconds, set the timeout where you initialize Sentry:

```csharp
using var sentry = SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.FlushTimeout = TimeSpan.FromSeconds(15);
});
```

### Hangfire Sends Recurring Job Schedules

Behavior change

Hangfire recurring jobs marked with `[SentryMonitorSlug]` now send their cron schedule and time zone with each check-in. Sentry creates monitors that don't exist yet. On each job's next run, Sentry also updates the schedule and time zone of existing monitors and keeps their other settings.

If you manage monitor schedules in Sentry, turn this off:

```csharp
using Hangfire;
using Sentry.Hangfire;

GlobalConfiguration.Configuration.UseSentry(options => options.SendMonitorConfig = false);
```

See [Hangfire](https://docs.sentry.io/platforms/dotnet/crons/hangfire.md) for more about cron monitoring with Hangfire.

### DecompressionMethods No Longer Includes Brotli

FYI

`SentryOptions.DecompressionMethods` now defaults to `GZip | Deflate`. In 6.x, it included every method, so the SDK asked your Sentry server for Brotli-compressed responses and decoded them. Sentry's responses to the SDK are small, so this shouldn't make a visible difference.

The new default keeps the SDK away from the .NET Brotli decoder, which has a security issue in unpatched runtimes. See [CVE-2026-111497](https://github.com/dotnet/announcements/issues/494). This matters most for self-contained, Native AOT and mobile apps, which carry their own runtime.

To accept Brotli-compressed responses again, add it back. `DecompressionMethods.Brotli` is available on .NET Core 3.0 and later:

```csharp
using System.Net;

SentrySdk.Init(options =>
{
    options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>";
    options.DecompressionMethods |= DecompressionMethods.Brotli;
});
```

## Optional cleanup

1 left

Deprecations and type tightening you can address later.

### Call UseSentry on WebApplicationBuilder

FYI

ASP.NET Core apps can now call `UseSentry` on `WebApplicationBuilder` and keep chaining. `builder.WebHost.UseSentry()` still works, so this change is optional.

In 6.x, `UseSentry` was only available on the web host:

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseSentry(options => options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>");
```

In 7.x, call it on the builder:

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.UseSentry(options => options.Dsn = "https://<key>@o<orgId>.ingest.sentry.io/<projectId>");
```

A helper declared in the `Microsoft.Extensions.Hosting` namespace needs a static call instead. The `AddServiceDefaults` method that .NET Aspire templates generate is one example. Inside that namespace, `web.UseSentry()` binds to the generic host overload from `Sentry.Extensions.Hosting`, even for a `WebApplicationBuilder`. The app then misses request data, the middleware and the transactions for incoming requests. Call the ASP.NET Core overload as a static method:

```csharp
using Microsoft.AspNetCore.Builder;

namespace Microsoft.Extensions.Hosting;

public static class Extensions
{
    public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder)
        where TBuilder : IHostApplicationBuilder
    {
        if (builder is WebApplicationBuilder web)
        {
            SentryWebApplicationBuilderExtensions.UseSentry(web);
        }
        else
        {
            builder.UseSentry();
        }

        return builder;
    }
}
```

When `UseSentry` from `Sentry.Extensions.Hosting` runs in an ASP.NET Core app, the SDK logs a warning through `ILogger` when the host starts.
