---
title: "Troubleshooting"
description: "Troubleshoot and resolve edge cases regarding known limitations and bundling."
url: https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting/
---

# Troubleshooting | Sentry for Flutter

If you need help solving issues with Sentry's Flutter SDK, you can read the edge cases documented here. If you need additional help, you can [ask on GitHub](https://github.com/getsentry/sentry-dart/issues/new/choose). Customers on a paid plan may also contact support.

## [Not Enough Stack Frames Captured or the Captured Frames are Unhelpful For Debugging](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#not-enough-stack-frames-captured-or-the-captured-frames-are-unhelpful-for-debugging)

### [What's the Problem?](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#whats-the-problem)

When errors occur in your Flutter app, you might notice that some error reports in Sentry don't show you the complete stack trace that led to the error. This missing information can make it harder to pinpoint where the problem originated in your code.

### [When This Problem Occurs](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#when-this-problem-occurs)

Sentry automatically captures error details and stack traces using Flutter and Dart's built-in error handling such as `FlutterError.onError`. However, sometimes the stack trace information is not available or becomes incomplete, especially when using `async` and `await` in your code.

When this happens, Sentry does its best to give you *some* debugging information, for example by calling `StackTrace.current` if there is none given by the `onError` hook, but it might not give you the complete picture.

### [Example of the Problem](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#example-of-the-problem)

Here's a simple example that demonstrates this issue:

```dart
Future<void> tryCatch() async {
  await foo();

  try {
    throw StateError('try catch');
  } catch (error) {
    // This is only an example, you should not do this in your code
    FlutterError.reportError(FlutterErrorDetails(exception: error));
  }
}

Future<void> foo() async {
  bar();
}

void bar() {
  // ...
}
```

If you run this code, you'll see that the error that we automatically capture is the following:

```bash
StateError: Bad state: try catch
  #0      FlutterError.reportError (package:flutter/src/foundation/assertions.dart:1204:14)
  #1      tryCatch (package:sentry_flutter_example/main.dart:769:18)
```

As you can see the stack trace is missing the `foo` and `bar` functions. This happens because Dart's async/await implementation can cause stack trace information to be lost during asynchronous operations. This is a known limitation of the Dart runtime itself, not a Sentry issue. You can learn more about this in [this Dart issue](https://github.com/dart-lang/sdk/issues/46318).

### [What Can You Do?](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#what-can-you-do)

In order to get better debugging information for these cases you can:

* Add relevant context to your Sentry events using [custom tags](https://docs.sentry.io/platforms/dart/guides/flutter/enriching-events/tags.md) and [breadcrumbs](https://docs.sentry.io/platforms/dart/guides/flutter/enriching-events/breadcrumbs.md) for critical paths in your application
* Consider using [Sentry's Structured Logs](https://docs.sentry.io/platforms/dart/logs.md) to capture additional debugging data alongside your errors

## [Support 16 KB Page Sizes on Android](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#support-16-kb-page-sizes-on-android)

Starting with Android 15, AOSP supports devices with a 16 KB page size. If your app uses NDK libraries (directly or via an SDK), you'll need to rebuild it for compatibility with these devices.

Update to Sentry Flutter SDK version `8.11.0` and above order to support 16 KB page sizes on Android devices.

Please read the [Android developer documentation](https://developer.android.com/guide/practices/page-sizes) to update and test your app with 16 KB page size support.

## ["Missing API declaration" after App Store review](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#missing-api-declaration-after-app-store-review)

Starting May 1, 2024, Apple requires all apps submitted to the App Store to provide a list of privacy-related APIs they use, including the reasons under which they use it. If you received an email from Apple with the message "ITMS-91053: Missing API declaration", your app doesn't fulfill the requirements. To solve this, follow our [Apple Privacy Manifest](https://docs.sentry.io/platforms/dart/guides/flutter/data-management/apple-privacy-manifest.md) guide.

## [Known Limitations](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#known-limitations)

* If you enable the `split-debug-info` and `obfuscate` features, you must upload [debug symbols](https://docs.sentry.io/platforms/dart/guides/flutter/upload-debug.md).

* Issue titles might be obfuscated (or minified on web) as we rely on the `runtimeType`, but they may not be human-readable. For iOS and Android, follow the [Sentry Dart Plugin guide](https://docs.sentry.io/platforms/dart/guides/flutter/upload-debug.md) to set up the obfuscation map which allows us to deobfuscate the issue tile. We’re currently exploring a solution for Web.

* Layout related errors are only caught by [FlutterError.onError](https://api.flutter.dev/flutter/foundation/FlutterError/onError.html) in debug mode. In release mode, they are removed by the Flutter framework. See [Flutter build modes](https://flutter.dev/docs/testing/build-modes).

* Use [inbound filters](https://docs.sentry.io/concepts/data-management/filtering.md) to exclude unhandled errors that are caught outside of your application in release builds. The SDK cannot filter these directly due to obfuscated stack traces.

* If your app runs on Windows and uses a Flutter version below `3.3.0`, you need to set the version and build number manually, see [this issue on GitHub](https://github.com/flutter/flutter/issues/73652). To do so:

  * Use Dart defines to build the app: `flutter build windows --dart-define=SENTRY_RELEASE=my_app@1.0.0+1`
  * Or, set the release on SentryOptions `options.release = 'my_app@1.0.0+1'` during SDK initialization.

## [Building Specific ABI on Android](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#building-specific-abi-on-android)

The Sentry Flutter SDK includes the Sentry Android SDK, which bundles multiple native libraries for multiple ABIs. Building a Flutter app for a specific ABI using the `--target-platform` argument, for example an ARM 32bit apk, looks like this, which should also include the `--split-per-abi` flag:

```bash
flutter build apk --target-platform=android-arm --split-per-abi
```

## [Running Sentry Within an Isolate](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#running-sentry-within-an-isolate)

If you have a Sentry instance running within a separate [Isolate](https://dart.dev/language/isolates) you must execute `Sentry.close()` before the Isolate completes, otherwise the Isolate won't shut down correctly.

## [Native Symbolication on Android](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#native-symbolication-on-android)

The configuration for symbolication of Native events (C/C++) is documented in our [Android Native Development Kit](https://docs.sentry.io/platforms/android/configuration/using-ndk.md) content. If you are having issues with symbolication in Flutter, check that your configuration is correct, as discussed in our Flutter content that covers [Uploading for Android NDK](https://docs.sentry.io/platforms/dart/guides/flutter/upload-debug.md#uploading-for-android-ndk)

## [Native Symbolication on iOS/macOS](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#native-symbolication-on-iosmacos)

Flutter `split-debug-info` and `obfuscate` flags are supported on iOS/macOS. They require compiling your app using Flutter, version `3.7.0` and above and the Sentry Flutter SDK, version `6.10.0` and above.

## [Source Context](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#source-context)

Source Context support requires compiling your app using the `split-debug-info` build parameter on Flutter `3.10.0` and above. You must also upload [debug symbols](https://docs.sentry.io/platforms/dart/guides/flutter/upload-debug.md) with the `upload_sources` option enabled.

## [Sentry Dart Plugin](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#sentry-dart-plugin)

If you are using the Sentry Dart Plugin to upload [Debug Symbols](https://docs.sentry.io/platforms/dart/guides/flutter/upload-debug.md#automatically-upload-debug-symbols), refer to the points below to resolve potential issues.

A Sentry `auth_token` can be generated at the [Organization Tokens ](https://sentry.io/orgredirect/organizations/:orgslug/settings/auth-tokens/)settings page.

Dart's `--obfuscate` option is required to be paired with `--split-debug-info` to generate a symbol map. See [Dart docs](https://github.com/flutter/flutter/wiki/Obfuscating-Dart-Code) for more information.

The `--split-debug-info` option requires setting an output directory. The directory must be an inner folder of the project's folder. See [Flutter docs](https://docs.flutter.dev/deployment/obfuscate#obfuscate-your-app) for more information.

Flutter's `build web` command requires setting the `--source-maps` parameter to generate source maps. See [Flutter GitHub Issue](https://github.com/flutter/flutter/issues/72150#issuecomment-755541599) for more information.

## [Issues with native crashes on Linux and/or Windows](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#issues-with-native-crashes-on-linux-andor-windows)

By default the Sentry Flutter SDK will enable native crash reporting on Linux and Windows with `crashpad`. The only exception is Windows ARM64 which uses `breakpad`. If you encounter any issues, you can set the `SENTRY_NATIVE_BACKEND` environment variable to an empty string to disable native crash reporting.

### [Crashpad Compile Error](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#crashpad-compile-error)

On Linux, compiling your Flutter Desktop app with the crashpad backend can fail if your clang toolchain is out of date.

* Update your clang to at least version 13, then try again.
* If you still encounter errors, please file an issue on our [Sentry Dart GitHub repository](https://github.com/getsentry/sentry-dart/issues/).

### [Java or JNI Errors when compiling on Flutter Desktop](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#java-or-jni-errors-when-compiling-on-flutter-desktop)

Since Sentry Flutter SDK version `9.0.0`, we improved how the SDK works on Android by switching from method channels to JNI (Java Native Interface) for certain operations.

However, there's a current limitation: Flutter automatically compiles the Dart JNI plugin for all platforms (iOS, Android, etc.), even when you're only building for one platform.

For example on Windows it will compile components such as `dartjni.dll` which requires a JDK (Java Development Kit) to be installed on your system.

Ideally it is possible to compile only for the chosen target platform to avoid unnecessary work, but this is currently blocked by [this Dart JNI issue](https://github.com/dart-lang/native/issues/1023).

If you run into problems, make sure you have a JDK installed on your computer. We recommend using version 17.

This does not affect your end users. Since we only use JNI code on Android, users on other platforms do not need Java installed. The JDK is only necessary as the developer because the Flutter tooling will compile the Dart JNI plugin for all platforms.

### [`SentryFlutter.init` Throws a `sentry_init failed` Error](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#sentryflutterinit-throws-a-sentry_init-failed-error)

On Linux, `SentryFlutter.init` automatically tries to use the crashpad backend. There are cases where the Flutter tooling overrides the permission of the crashpad binary, causing the initialization to fail.

To resolve this:

1. Search for the following code block in your `linux/CMakeLists.txt` file:

`<your-app>/linux/CMakeLists.txt`

```cmake
# Find this code block
if(PLUGIN_BUNDLED_LIBRARIES)
  install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
    DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
    COMPONENT Runtime)
endif()
```

2. Once you find it, replace it with the following code block:

`<your-app>/linux/CMakeLists.txt`

```cmake
foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
  if("${bundled_library}" STREQUAL "$<TARGET_FILE:crashpad_handler>")
    install(PROGRAMS "${bundled_library}"
      DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
      COMPONENT Runtime)
  else()
    install(FILES "${bundled_library}"
      DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
      COMPONENT Runtime)
  endif()
endforeach()
```

This allows cmake to use the correct install command `install(PROGRAMS ..)` instead of `install(FILES ..)` which strips the executable bit.

## [Sentry Android Gradle Plugin Circular Dependency](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#sentry-android-gradle-plugin-circular-dependency)

If you encounter a circular dependency error when building your Android app with the Sentry Android Gradle Plugin, this is typically caused by using an older version of the Android Gradle Plugin (AGP).

### [Error Example](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#error-example)

You might see an error similar to:

```bash
Circular dependency between the following tasks:
:app:compileReleaseJavaWithJavac
:app:generateSentryProguardUuidProductionRelease
```

### [Solution](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#solution)

Update your Android Gradle Plugin to version **7.4** or higher. In your `android/build.gradle` (project-level) file:

`android/build.gradle`

```groovy
buildscript {
    dependencies {
        classpath("com.android.tools.build:gradle:7.4.0") // or higher
    }
}
```

Or if using the plugins block in your `android/app/build.gradle`:

`android/app/build.gradle`

```groovy
plugins {
    id "com.android.application" version "7.4.0" // or higher
}
```

AGP 7.4+ introduced new APIs for injecting into assets that the Sentry Android Gradle Plugin uses to avoid this circular dependency. Since AGP 7.4 was released in 2023, we recommend upgrading to the latest stable version.

For more information, see [GitHub issue #756](https://github.com/getsentry/sentry-android-gradle-plugin/issues/756).

## [Zone Mismatch Error on Web](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#zone-mismatch-error-on-web)

By default, the Sentry Flutter SDK creates a custom zone on web for automatic error and breadcrumb tracking. This can lead to zone mismatch errors when your application calls `WidgetsBinding.ensureInitialized()` before initializing Sentry.

To resolve this issue, use the `Sentry.runZonedGuarded` method to initialize both your application and Sentry within the same zone. This approach ensures proper zone consistency throughout your application:

```dart
import 'package:flutter/widgets.dart';
import 'package:sentry_flutter/sentry_flutter.dart';

Future<void> main() async {
  Sentry.runZonedGuarded(() async {
    WidgetsBinding.ensureInitialized();

    await SentryFlutter.init(
      (options) {
        // your config...
      },
      appRunner: () => runApp(
        SentryWidget(
          child: MyApp(),
        ),
      ),
    );
  }, (error, stackTrace) {
    // Note: Errors in this zone are already sent to Sentry automatically.
    // This callback lets you add your own custom error handling (like logging)
    // in addition to Sentry's reporting.
  });
}
```

## [Using Flutter Multi-view for Web](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#using-flutter-multi-view-for-web)

Multi-view embedding was introduced in Flutter 3.24. You'll find a detailed guide about it in the [Flutter docs](https://docs.flutter.dev/platform-integration/web/embedding-flutter-web) .

Using Sentry in a multi-view application is possible, but there are some limitations you should be aware of. The following features don't currently support multi-view:

* Screenshots via the `SentryScreenshotWidget` (which is part of the `SentryWidget`)
* User interaction integration via the `SentryUserInteractionWidget` (which is part of the `SentryWidget`)
* Window and Device events via the `WidgetsBindingIntegration`

To prevent the `WidgetsBindingIntegration` from loading by default, you'll need to remove the integration as shown below:

```dart
// ignore: implementation_imports
import 'package:sentry_flutter/src/integrations/widgets_binding_integration.dart';
...
SentryFlutter.init(
  (options) {
    ...
    final integration = options.integrations
        .firstWhere((element) => element is WidgetsBindingIntegration);
    options.removeIntegration(integration);
  },
  // Init your App.
  appRunner: appRunner,
);
```

### [Example Application](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#example-application)

Copy the `main.dart` file into the `lib` folder of your existing project. This file already contains the code of the `multi_view_app.dart` from the [`flutter documentation`](https://docs.flutter.dev/platform-integration/web/embedding-flutter-web#handling-view-changes-from-dart). Next, copy the `flutter_bootstrap.js` file and the `index.html` file into the `web` folder.

Make sure you're using **Flutter 3.24** or newer and run the application.

Now you should be able to see **two** instances of the same application side by side, with different **ViewIds** in the `body`.

`main.dart`

```dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:sentry_flutter/src/integrations/widgets_binding_integration.dart';
import 'dart:ui' show FlutterView;

const String exampleDsn = '___DSN___';

Future<void> main() async {
  await SentryFlutter.init(
    (options) {
      options.dsn = exampleDsn;
      final integration = options.integrations
        .firstWhere((element) => element is WidgetsBindingIntegration);
      options.removeIntegration(integration);
    },
    // Init your App.
    appRunner: () => runWidget(
      MultiViewApp(
        viewBuilder: (BuildContext context) => DefaultAssetBundle(
          bundle: SentryAssetBundle(),
          child: const MyApp(),
        ),
      ),
    ),
  );
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorObservers: [
        SentryNavigatorObserver(),
      ],
      home: Scaffold(
        body: Center(
          child: Text(
              'Sentry Flutter Example (ViewId:${View.of(context).viewId})'),
        ),
      ),
    );
  }
}

// multi_view_app.dart

// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/// Calls [viewBuilder] for every view added to the app to obtain the widget to
/// render into that view. The current view can be looked up with [View.of].
class MultiViewApp extends StatefulWidget {
  const MultiViewApp({super.key, required this.viewBuilder});

  final WidgetBuilder viewBuilder;

  @override
  State<MultiViewApp> createState() => _MultiViewAppState();
}

class _MultiViewAppState extends State<MultiViewApp>
    with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _updateViews();
  }

  @override
  void didUpdateWidget(MultiViewApp oldWidget) {
    super.didUpdateWidget(oldWidget);
    // Need to re-evaluate the viewBuilder callback for all views.
    _views.clear();
    _updateViews();
  }

  @override
  void didChangeMetrics() {
    _updateViews();
  }

  Map<Object, Widget> _views = <Object, Widget>{};

  void _updateViews() {
    final Map<Object, Widget> newViews = <Object, Widget>{};
    for (final FlutterView view
        in WidgetsBinding.instance.platformDispatcher.views) {
      final Widget viewWidget = _views[view.viewId] ?? _createViewWidget(view);
      newViews[view.viewId] = viewWidget;
    }
    setState(() {
      _views = newViews;
    });
  }

  Widget _createViewWidget(FlutterView view) {
    return View(
      view: view,
      child: Builder(
        builder: widget.viewBuilder,
      ),
    );
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ViewCollection(views: _views.values.toList(growable: false));
  }
}
```

## [Which Native SDK Versions Are Bundled With Each Flutter SDK Release?](https://docs.sentry.io/platforms/dart/guides/flutter/troubleshooting.md#which-native-sdk-versions-are-bundled-with-each-flutter-sdk-release)

You can find a complete list of bundled Android, Cocoa, JavaScript, and Native SDK versions for each Flutter SDK release in the [sdk-versions.md](https://github.com/getsentry/sentry-dart/blob/main/docs/sdk-versions.md) file on GitHub.
