NDK symbol upload

Upload shared object symbol files to allow BugSnag to make your Android NDK stack traces readable.


For Android applications, when native code is used it will be compiled into shared object files, usually with the symbol names removed.

In order to replace the obfuscated data with a human-readable stack trace, BugSnag requires a shared object file that does contain those symbols.

This documentation is for the latest NDK symbol upload API.

To use the latest API you will need:

  • a compatible version of the BugSnag library in your app:

    • bugsnag-android v5.26.0+
    • bugsnag-flutter v2.3.0+
    • bugsnag-js (React Native) v7.17.4+
    • bugsnag-unity v7.1.1+
      • note this applies to custom NDK binaries only. For Unity-generated binaries please continue to use the legacy endpoint. See Unity guide.
    • bugsnag-unreal-engine v1.5.1+
  • to be using the BugSnag upload endpoints or a recent version of On-premise (v3.2211.0+ single machine or v5.2211.0+ of clustered)

If you cannot use the latest API you need to use the legacy endpoints for which documentation can be found on our legacy page.

If switching an existing project to the new mechanism, some stack frames may symbolicate differently than they did with the old mechanism, resulting in new error groups. This should only affect stack frames that the old mechanism was unable to symbolicate.

Automating uploads using BugSnag tools

See the Showing full stacktraces guide for instructions on setting up this upload in your build system using the BugSnag CLI or our Gradle plugin.

If you’re building an Android project from Unity, the best way to send your shared object symbol files to BugSnag is to use our Gradle plugin for Unity.

Manually uploading files

In cases where you cannot use our tools, you’ll need to manually upload a shared object file to BugSnag using our API.

Extracting symbols

The intermediate shared object files generated for an Android NDK build will contain the symbols. Since BugSnag only requires the symbols, we recommend that you remove the executable code in order to reduce file size.

To check whether a shared object file contains debug symbols, run the file command with the path to the shared object file. The output will include stripped if the file has been stripped of debug symbols, and debug_info, not stripped if it contains debug symbols.

To extract symbols from a full shared object file that contains executable code and symbols, you must run the objcopy command with the following parameters:

objcopy --compress-debug-sections=zlib \
        --only-keep-debug \
        <path_to_intermediate_so_file> \

If you do not have an objcopy in your path you will be able to find one using find $ANDROID_HOME/ndk -iname "*objcopy" on macOS, Linux, and Cygwin. Note that for NDK version 23 and higher you should use llvm-objcopy while for version 22 and lower you must use objcopy (which is GNU objcopy).

Uploading files

To send shared object files containing symbols to BugSnag, POST them to https://upload.bugsnag.com/ndk-symbol (or your on-premise equivalent) with the following parameters:

  • soFile - the path to the shared object file.
  • apiKey - your BugSnag integration API key for this application.
  • appId (optional) - the Android applicationId for this application.
  • versionCode (optional) - the Android versionCode for this application release.
  • sharedObjectName (optional) - the name of the shared object that the symbols are for.
  • versionName (optional) - the Android versionName for this application release.
  • projectRoot (optional) - a path to remove from the beginning of the filenames in the mapping file
  • overwrite (optional) - overwrite any existing mappings for this version of your app.

The error event is mapped to the appropriate symbols using the “Build ID” that is encoded into the shared object files both uploaded here and deployed to the end-user’s device. The optional identificatory fields are simply for information when looking at the list of uploaded files in the BugSnag dashboard. They are not used in the symbolication process.

cURL example

Here’s an example request with curl:

$ curl --http1.1 https://upload.bugsnag.com/ndk-symbol \
    -F soFile=@/path/to/objcopy/output \
    -F apiKey=YOUR_API_KEY_HERE \
    -F versionCode=123 \
    -F appId=com.example.android.app \
    -F sharedObjectName=libmy-ndk-library.so \
    -F versionName=2.3.0

Response codes

If the file is accepted then an HTTP 202 response will be returned with the body “Accepted”.

If not, there are several possible problems which will be indicated with an HTTP 4XX response:

  • duplicate symbol file - indicates that BugSnag already has a file with this id. You can ignore this error by using the overwrite parameter.
  • invalid apiKey - indicates that the provided apiKey doesn’t correspond to a BugSnag project.
  • invalid file format - indicates that the uploaded file was in an incorrect format (not a valid shared object file)