282

When I want to release a new flutter app bundle to the Playstore. I get this error:

This App Bundle contains native code, and you've not uploaded debug symbols. We recommend you upload a symbol file to make your crashes and ANRs easier to analyze and debug.

I can't find any way to fix this. I'm new with flutter and releasing app's and getting a bit desperate...

Any help would be fantastic.

When I add android.defaultConfig.ndk.debugSymbolLevel = 'FULL' (on line 1) to the app/build.gradle, as suggested in https://developer.android.com/studio/preview/features#native-crash-symbolization, I get this error in the Android studio terminal. I use this command:

flutter build appbundle

Error in Terminal:

FAILURE: Build failed with an exception. * Where: Build file 'C:\Users\filip\AndroidStudioProjects\ehbo\android\app\build.gradle' line: 1 * What went wrong: A problem occurred evaluating project ':app'. > Could not get unknown property 'android' for project ':app' of type org.gradle.api.Project. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. * Get more help at https://help.gradle.org BUILD FAILED in 3s Running Gradle task 'bundleRelease'... Running Gradle task 'bundleRelease'... Done 4,3s Gradle task bundleRelease failed with exit code 1 
2
  • It seems you need to upload deobfuscation / symbolication file . check below link: support.google.com/googleplay/android-developer/answer/… Commented Jun 25, 2020 at 9:55
  • 1
    It's just beta problems, this functionality is not in stable gradle release yet, only in 4.1 So looks like Play console beta is for android studio beta now. Commented Jun 26, 2020 at 8:11

20 Answers 20

310

Reproduce the next steps and this warning will disappear.

  1. Go to [YOUR_PROJECT]\build\app\intermediates\merged_native_libs\release\out\lib

For some the path might be [YOUR_PROJECT]\app\build\.... and not [YOUR_PROJECT]\build\app\.... like mentioned above.

Note that 3 folders exist inside

  • arm64-v8a
  • armeabi-v7a
  • x86_64
  1. Select these 3 folders and create a .zip file. The name doesn't matter.

[PLEASE NOTE THAT I HAVEN'T COMPRESSED THE ./lib FOLDER]

  1. Upload this new *.zip file as a Symbol File.

.

The newest update, for us (8-Nov 2023) the folder exists in [YOUR_PROJECT]\build\app\intermediates\merged_native_libs\release\out\lib


Update 2025

  1. Directory Path: /app/build/intermediates/merged_native_libs/release/mergeReleaseNativeLibs/out/lib

  2. Zip all the directories in this location.

  3. To remove MacOS files (Source: https://stackoverflow.com/a/76621112/9636037)

    zip -d Archive.zip "__MACOSX*" 
  4. To upload to Play Console. In the create a new release flow, after uplodaing the app bundle, you can find this option in the bundle.

Sign up to request clarification or add additional context in comments.

10 Comments

For anyone wondering how to upload the Symbols file ... support.google.com/googleplay/android-developer/answer/…
Thanks so much for this! Silly me thought that the *.symbols files were what needed to be uploaded for the "Native debug symbols" and not a zip of folders containing *.so files.
For me the folder is actually at: [YOUR_PROJECT]\build\app\intermediates\merged_native_libs\release\out\lib
To prevent macOS files in the zip, use terminal instead: 1. cd you_project_path/build/app/intermediates/stripped_native_libs/productionRelease/out/lib 2. rm .DS_Store 3. zip -r symbols.zip . And for anyone getting errors not accepting the .so files from this directory use build/app/intermediates/stripped_native_libs/productionRelease/out/lib instead.
So.. do I need to do this every time?
|
76

If talking about Flutter, looks like the Flutter team needs to change some source files for the NDK, because it does not see where from to generate debug symbols.

Here is an issue thread: https://github.com/flutter/flutter/issues/60240

Setup steps are so:

  • Pre-condition: Intall Android studio 4.1+ and Gradle 4.1+
  1. Install NDK (Side by Side) in SDK manager enter image description here

  2. Write path to NDK in local.properties enter image description here

  3. Add in app/build.gradle (last line) android.buildTypes.release.ndk.debugSymbolLevel = 'FULL' enter image description here

6 Comments

I followed the same I get this, * What went wrong: A problem occurred evaluating project ':app'. > Could not get unknown property 'ndk' for BuildType_Decorated{name=release,
@MSaudi See this link - I had the same problem. It was resolved after upgrading my gradle version. See stackoverflow.com/a/63436935/7015661
ndk.dir is depreciated
Is this option for Flutter apps better than compressing the \build\app\intermediates\merged_native_libs\release\out\lib symbols? Using the NDK is automatic yeah, but the symbols produced by the NDK seems to be much much smaller than the symbols located in the mencioned folder. For my app, NDK size was 5kB and merged_native_libs was 12MB
@Bugzilla, why is smaller not preferred?
|
50

Before you can upload debug symbols files, you must be using Android Gradle plugin version 4.1 or higher.

Looks like it will come only with Android Studio 4.1, because I can only get Gradle 4.0.0 automatically now.

So I suggest you to return classic Play console and it will let you through :)

UPDATE: So just use an updated Gradle and add NDK debug symbols to the build now

8 Comments

Dang, I think you're right. I can also go only up to 4.0 with Android Studio 4.0.
Ok Thanks I will try it with the classic Play console
YES! It worked (I used the classic Play Console). Thank you so much!
I don't think so, there will be some changes that we need to do in the future. What if I want to the new Play Console?
Added a new description in the post below. The setup is right, but looks like Flutter team needs to update some building things
|
31

you can make these zip file by go to build\app\intermediates\merged_native_libs\release\out\lib inside your Flutter project

and compress the folders into symbols.zip, now upload it into the google play console

5 Comments

after you get the .zip, where in google play can you upload this file please?
What exactly are you ziping ? .so files ? something else ?
everything inside the lib
It's not working anymore
27

The Answer was given by Shakle will be not useful as per the following message on Play Console.

The old version of Play Console will be discontinued from November 2, 2020 You’re already using the new Play Console, so you don’t need to do anything. A few features are going away if you want to check them one last time.

It's just a warning, nothing else. Just go ahead.

If you don't want any warning, Go to this link and follow the steps:

https://support.google.com/googleplay/android-developer/answer/9848633?hl=en

You can use the new version of the play store as it is.

Comments

11

I had a similar problem. What really helped me:

  1. Make sure your Android Gradle plugin version is 4.1 or later.
  2. Install NDK (Side by Side) in SDK manager.
  3. Install CMake in SDK manager.
  4. Add
 ndkVersion <ndkVersion> ndk { debugSymbolLevel 'FULL' } 

to app/build.gradle

My final build.gradle:

... android { compileSdkVersion 30 defaultConfig { applicationId "com.example.app" minSdkVersion 21 targetSdkVersion 30 versionCode 28 versionName "1.0.59" ndkVersion "23.1.7779620" ndk { debugSymbolLevel 'FULL' } } buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } configurations { compile.exclude group: 'com.google.zxing' } } ... 

I hope this will help you and save you time

5 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
To make this work in vsCode, I had to add the now deprecated option ndk.dir=/path/to/ndk in the local.properties file.
ndkVersion "23.1.7779620" this or it can be anything?
@DragonFire the number you add has to match the version you installed (via sdk manager)
Works great. Thanks!
8

If you want to solve this warning error: This App Bundle contains native code, and you've not uploaded debug symbols. We recommend you upload a symbol file to make your crashes and ANRs easier to analyze and debug. Make sure also to install CMake

This will happen if your gradle version is higher than 4.0 Place this code into your build.gradle file

android { compileSdkVersion 28 defaultConfig { applicationId 'com.example.myproject' minSdkVersion 21 targetSdkVersion 28 versionCode 1 versionName "1.0.0" ndk { debugSymbolLevel 'FULL' } } 

5 Comments

@Rishav did you manage to solve it in React Native?
@LawrenceMacharia No. I realized that I don't care and everything is meaningless.
this solution worked for me with React-Native, but for my case, I had to install CMake and update my NDK to version 23.0.7599858, then I updated it on build.gradle(app) and finally followed this solution: stackoverflow.com/a/65367767/6674314
@acuriousguy solution worked for me with React Native as well. Make sure to install CMake: developer.android.com/studio/projects/install-ndk#kts and set the debugSymbolLevel to FULL instead of SYMBOL_TABLE
@LawrenceMacharia In my case, for React Native, I had to manually zip up these files here: app/build/merged_native_libs/myAppRelease/out/lib and upload Native Debug Symbols - after moving back to the "Edit Release" step, and then tapping "Review Release" the error went away!
8

Instead of creating and uploading zip files, you can include the following to your app\build.gradle file:

buildTypes { debug { // This is just here for local testing and is optional. firebaseCrashlytics { nativeSymbolUploadEnabled true unstrippedNativeLibsDir file("build/app/intermediates/merged_native_libs/debug/out/lib") } ndk { debugSymbolLevel 'SYMBOL_TABLE' } } release { // .. firebaseCrashlytics { // Insert this nativeSymbolUploadEnabled true unstrippedNativeLibsDir file("build/app/intermediates/merged_native_libs/release/out/lib") } ndk { // replace with 'FULL' if you need more info, // but note that it will increase the file size of your appbundle dramatically. debugSymbolLevel 'SYMBOL_TABLE' } } } 

Here is some documentation for reference: https://firebase.google.com/docs/crashlytics/ndk-reports#upload-symbols-external-dependencies

And if you're unclear about how to set up automatic uploading of native symbols, try adding this:

buildTypes { ... } // Your build types from the above snippet. tasks.whenTaskAdded { task -> if (task.name.startsWith('assemble') && task.name != "assembleReleaseAndroidTest" && task.name != "assembleDebugAndroidTest") { String taskName = "uploadCrashlyticsSymbolFile" + task.name.substring('assemble'.length()) task.finalizedBy taskName doFirst { println "Running Gradle task '$taskName'..." } } } 

More info for building gradle tasks here: https://docs.gradle.org/current/userguide/tutorial_using_tasks.html

Also, ensure that you have NDK and CMAKE installed in your IDE's SDK Manager.

Hope that helps!

Comments

7

Simple approach, go to \build\app\intermediates\merged_native_libs\release\out\lib , you will find 3/4 folders , zip those , upload this ZIP from release option ( upload Symbol File ). Warning will be gone after bundle review.

Comments

7

Update for Oct, 2024

Following Gabriel's neat answer, I wanted to automate this process as well. However, that solution wasn't working for me. After two days of trial & error, I realized that that solution had in my case been silently failing (i.e. no errors logged) because the suggested from and destinationDirectory paths were different in my (Flutter) project. So if you are facing similar problems, the following is an expanded solution that adds some checks & logs, allowing you to easier isolate and address any issues specific to your setup now or in the future.

My project setup

Note: mine is a Flutter project but the below solution should be similar in other projects.

A) Update your android/app/build.gradle file

Note: to learn about "tasks" in Gradle, check out the official docs. Also, in the below solution, as suggested by one of the comments in one of the other answers, I am checking for (and removing) some hidden files that are generated by macOS, in case you are on a Mac. That step seems redundant though when the zip is generated programmatically like I do in my solution, but I left it in as a precaution.

Add import java.nio.file.Paths to the top of the android/app/build.gradle file. Then add everything else after the flutter {...} block here:

import java.nio.file.Paths plugins { ... } android { ... } flutter { source = "../.." } // STEP 1: Create and register the `zipNativeDebugSymbols` task to zip debug symbol files for manual upload to the Google Play store. def zipNativeDebugSymbols = tasks.register('zipNativeDebugSymbols', Zip) { // Optional: this sets some info about the task (to verify, run `./gradlew app:tasks` in the /android folder to see this task listed) group = 'Build' description = 'Zips debug symbol files for upload to Google Play store.' // Set the input source directory (this is where the debug symbol files should be after the `bundleRelease` process has finished) def libDir = file('../../build/app/intermediates/merged_native_libs/release/out/lib') from libDir // Include all subfiles and directories include '**/*' // Set the name for the output zip file archiveFileName = 'native-debug-symbols.zip' // Set the destination directory for the output zip file def destDir = file('../../build/app/outputs/bundle/release') destinationDirectory = destDir doFirst { // Ensure the paths are correct for the required directories and that they indeed were created / exist (the preceding task `bundleRelease` creates these directories) checkDirectoryExists(libDir, 'Library directory') checkDirectoryExists(destDir, 'Destination directory') } doLast { println '✅ zipNativeDebugSymbols: created native-debug-symbols.zip file' // Optional: if running on macOS, clean up unwanted files like '__MACOSX' and '.DS_Store' in the now created zip file // The '__MACOSX' and '.DS_Store' files seem to be added only when manually creating ZIPs on macOS, not programmatically like here. Nevertheless, no harm in leaving this in as a precaution. if (System.properties['os.name'].toLowerCase().contains('mac')) { println ' running on Mac...' // Combine destination path and zip file name def zipPath = Paths.get(destinationDirectory.get().asFile.path, archiveFileName.get()).toString() // Ensure the zip file exists if (new File(zipPath).exists()) { println " removing any '__MACOSX' and '.DS_Store' files from the zip..." checkAndRemoveUnwantedFiles(zipPath, '__MACOSX*') checkAndRemoveUnwantedFiles(zipPath, '*.DS_Store') } else { println '❌ zip file does not exist: $zipPath' } } println '✅ zipNativeDebugSymbols: finished creating & cleaning native-debug-symbols.zip' } // Optional: force the task to run even if considered up-to-date outputs.upToDateWhen { false } println '✅ zipNativeDebugSymbols: task registered and configured' } // STEP 2: Configure the `zipNativeDebugSymbols` task to run after `bundleRelease` tasks.whenTaskAdded { task -> if (task.name == 'bundleRelease') { // `finalizedBy` ensures `zipNativeDebugSymbols` runs after `bundleRelease` is complete task.finalizedBy zipNativeDebugSymbols } } //// ----------- HELPER METHODS -------------- //// // Helper method to check if a directory exists def checkDirectoryExists(File dir, String description) { if (dir.exists()) { println '✅ zipNativeDebugSymbols: found ${description} ${dir}' } else { println '❌ ${description} does not exist: ${dir}' } } // Helper method to check for unwanted files and remove them def checkAndRemoveUnwantedFiles(String zipPath, String pattern) { def output = new ByteArrayOutputStream() exec { commandLine 'sh', '-c', "zipinfo $zipPath | grep '$pattern'" standardOutput = output errorOutput = new ByteArrayOutputStream() ignoreExitValue = true } if (output.toString().trim()) { println "✅ zipNativeDebugSymbols: found '$pattern' in the zip. Removing it..." exec { commandLine 'sh', '-c', "zip -d $zipPath '$pattern' || true" } } } 

B) Generate files and upload to Google Play store

1. Generate the files for upload:

  • From the root of your project, run flutter clean && flutter build appbundle.
  • Locate the folder that contains the generated files to upload, which is the folder you have defined in def destDir = .... In my case, it is in [project_name]/build/app/outputs/bundle/release. You should have two files in there: app-release.aab and native-debug-symbols.zip.

2. Upload to Google Play store:

  • Upload your app bundle (app-release.aab) to Google Play store.
  • Next, upload your debug symbols zip file (native-debug-symbols.zip) as well. If you don't know how, follow the instructions here in the section Step 2: Upload a deobfuscation or symbolication file.

Voila! That is it. Hope this saves you days of scratching your head like I did.


Helpful debugging info

In case you want to play around a little to understand Gradle and the above tasks better, here are some useful CLI commands. Note that they have to be run from your android/ directory. Also, for a Flutter project the base command here is ./gradlew but I'm guessing it is e.g. just gradlew for other projects.

  • ./gradlew --help displays all available commands
  • ./gradlew --version displays what Gradle version you are using, i.e. what you have set in your android/gradle/wrapper/gradle-wrapper.properties > distributionUrl=....
  • ./gradlew tasks lists all available Gradle tasks for the project (android/build.gradle), showing which tasks can be executed.
  • ./gradlew app:tasks lists all available Gradle tasks specifically for the app module (android/app/build.gradle).
  • ./gradlew clean cleans the build directory by removing all generated files, forcing a fresh build the next time tasks are run. Note: flutter clean achieves this as well.
  • ./gradlew bundleRelease builds the Android App Bundle (aab) in release mode, which is the app bundle that you upload to Google Play.
  • ./gradlew help --task bundleRelease Displays detailed information about the bundleRelease task, including its description, inputs, outputs, and other task properties.
  • ./gradlew zipNativeDebugSymbols --rerun-tasks --quiet runs the given task, e.g. the zipNativeDebugSymbols here, forcing it to rerun all tasks without showing any output unless there are errors.
  • ./gradlew zipNativeDebugSymbols --rerun-tasks --info runs the given task, e.g. the zipNativeDebugSymbols here, forcing it to rerun all tasks and displaying detailed information about the build process.
  • ./gradlew --scan creates a build scan with detailed performance and diagnostic data.

1 Comment

I have the error R8: com.android.tools.r8.ResourceException. I had to replace whenTaskAdded by configureEach. found here : stackoverflow.com/a/76801632
3

I just upgraded ndk from 21.4.7075529 to 22.1.7171670, and now I get the debug symbols.

I'm using com.android.tools.build:gradle:7.1.1 and React Natvive 0.69 BTW.

1 Comment

Oh my goodness, I've spent almost an entire day on this problem! Thank you for posting - that helped me.
3

For Mac Users:

Go to build\app\intermediates\merged_native_libs\release\out\lib inside your Flutter project, and compress the folders (arm64-v8a, armeabi-v7a, x86, x86_64) into Archive.zip.

Then cd [into the folder that contains Archive.zip]. Then run the command

zip -d Archive.zip "__MACOSX*" 

to get rid of the Mac __MACOSX files. Now upload it into the google play console. If not getting rid of the __MACOSX files, then google play console will give error on uploading -

"The native debug symbols contain an invalid directory __MACOSX"

Comments

2

For fixing it in the Visual Studio Code: you should first download the NDK from the android's website.

  • Extract the zip file to a folder named ndk and place it under your - already installed - Android SDK folder. Like this: Android/sdk/ndk

  • Then open app/build.gradle.

  • Under the Android section. Add ndkPath property as follows: ndkPath = <ndk-dir>

app/build.gradle ndkPath property

  • At the end of app/build.gradle add android.buildTypes.release.ndk.debugSymbolLevel = 'full'

  • The next appbundle, built by flutter build appbundle command should not give any errors on the play store about native debug symbols.

a more thorough explanation is here

Comments

2

Update Jan, 2025.

As of today, Gabriel Logan's solution still works, but a small tweak is needed since play store is not accepting 'mips' and 'armeabi' folders. Notice the "exclude statements".

project/app/build.gradle:

tasks.register('zipNativeDebugSymbols', Zip) { from 'build/intermediates/merged_native_libs/release/mergeReleaseNativeLibs/out/lib' exclude 'armeabi*' exclude 'mips' archiveFileName = 'native-debug-symbols.zip' destinationDirectory = file('build/outputs/bundle/release') } tasks.configureEach { task -> if (task.name == 'bundleRelease') { task.finalizedBy zipNativeDebugSymbols } } 

Comments

1

I have the exact same issue.

Possible solutions:

  1. Use the Google classic Play console
  2. Gradle 4.1 is now released with Android Studio 4.1

Comments

1

I created a windows batch file to build and zip the native libraries.

This DOES NOT work

Compress-Archive -Path .\build\app\intermediates\merged_native_libs\release\out\lib\* -DestinationPath .\native_symbols.zip

Using a 3rd party app works

C:\<your path>\7-Zip\7z.exe a native_symbols.zip .\build\app\intermediates\merged_native_libs\release\out\lib\*

The only difference I can see is that "Compress-Archive" discards the "a" archive file attribute.

Comments

1

As skyllet already answered, this procedure works, if you want to automate the process so you don't have to do it manually every time

You can add this code below in android/app/build.gradle

task zipNativeDebugSymbols(type: Zip) { from 'build/intermediates/merged_native_libs/release/mergeReleaseNativeLibs/out/lib' archiveFileName = 'native-debug-symbols.zip' destinationDirectory = file('build/outputs/bundle/release') } tasks.whenTaskAdded { task -> if (task.name == 'bundleRelease') { task.finalizedBy zipNativeDebugSymbols } } 

Under dependencies at the end of your build.gradle

This will do what the guy showed, but automatically, and will send the zip along with the aab

1 Comment

Happy too soon. Started getting this error after adding this code stackoverflow.com/questions/78026765/…
0

I was able to get Flutter to build native debug symbols using Android Gradle Plugin (AGP) 4.1.0, installing corresponding NDK version and adding the appropriate config to android/app/build.gradle on macOS (but it should also work on Windows/Linux).

  1. Optional: Run flutter build appbundle and take note of the .aab file size
  2. Check what version of AGP you're using in android/build.gradle by looking in dependencies e.g. com.android.tools.build:gradle:4.1.0 is 4.1.0
  3. Check which version of NDK you need. Assuming your AGP is 4.1.0 the NDK version you want to install is 21.1.6352462 (for other AGP versions check mappings here)
  4. Install specific NDK version using Android Studio. Alternatively you can use sdkmanager and the CLI: $ANDROID_HOME/tools/bin/sdkmanager --install "ndk;21.1.6352462"
  5. In android/app/build.gradle, under android.defaultConfig add ndk { debugSymbolLevel 'FULL' } aka set android.defaultConfig.ndk.debugSymbolLevel = 'FULL' as per this
  6. Run flutter build appbundle. The .aab should now contain native debug symbols and be larger than the previous build in step 0

Troubleshooting: If you get any errors around CMake I didn't explicitly install it but you might need to, especially if you're using Windows, and you can do so using Android Studio.

Comments

0

This is an update code from PravyNandas Tested in Android Studio Ladybug Feature Drop | 2024.2.2 Patch 2 with AGP version 8.8.2

Add it to build.gradle.kts(Module:app)

 tasks.register<Zip>("zipNativeDebugSymbols") { from("build/intermediates/merged_native_libs/release/mergeReleaseNativeLibs/out/lib") exclude("armeabi*") exclude("mips") archiveFileName.set("native-debug-symbols.zip") destinationDirectory.set(file("release")) } afterEvaluate { tasks.named("bundleRelease") { finalizedBy("zipNativeDebugSymbols") } } 

This code defines a task zipNativeDebugSymbols to create a zip file of release debug symbols, excluding armeabi and mips architectures, and places it in the release directory.

It then configures the bundleRelease task to always run zipNativeDebugSymbols afterward, ensuring debug symbols are zipped after building the release bundle.

Comments

-1

screenshot

My issue was this:

This App Bundle contains native code, and you've not uploaded debug symbols. We recommend you upload a symbol file to make your crashes and ANRs easier to analyze and debug.

Fix successfully just upload native debug symbols from the image reference directory shown.

1 Comment

Hi Jamshed, thanks for taking the time to post, however, your answer is exactly the same as the most upvoted answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.