Three reliable ways to get your iOS dSYM debug symbols into Sentry, using sentry-cli, an Xcode build phase, or automatic upload, so your crash reports show real function names and line numbers.
When your iOS app crashes, the operating system produces a report full of memory addresses, hexadecimal offsets that mean nothing on their own. A dSYM file, short for debug symbol file, is the mapping that translates those addresses back into function names, source file paths, and line numbers. Sentry symbolicates crashes on its servers, which means it needs your dSYM files uploaded ahead of time to do that translation. Without them, your crash issues in the Sentry dashboard will show unsymbolicated frames that are nearly useless for debugging. Every time you build a release, Xcode generates fresh dSYMs tied to that exact binary through a unique identifier called the debug ID or UUID. Sentry matches an incoming crash to the correct dSYM by that identifier, so uploading the wrong build's symbols will not help. This is why dSYM upload needs to be automated as part of your build and release process rather than done by hand, because doing it manually is error-prone and easy to forget on the one release that crashes.
Before uploading anything, confirm Xcode is producing dSYM files at all. Open your project, select the target, and go to Build Settings. Search for Debug Information Format. For your Release configuration, and typically for Archive builds, this should be set to DWARF with dSYM File. If it is set to just DWARF, no separate dSYM file is generated and you will have nothing to upload. Debug configurations often use plain DWARF for faster builds, which is fine because you rarely symbolicate simulator debug crashes, but your Release and Archive builds must produce dSYM files. After an Archive build, you can find the dSYMs inside the .xcarchive package under the dSYMs folder; right-click the archive in Xcode Organizer and choose Show in Finder, then show package contents. Confirming this setting first saves a great deal of confusion, because no upload method can send files that were never created. It is also worth confirming that no build script or third-party tool strips the symbols after they are generated; some crash-reporting setups or size-optimization scripts run strip on the binary or delete dSYMs, which quietly defeats symbolication even when the build setting is correct. With DWARF with dSYM File selected, every release build will emit the symbols Sentry needs.
The sentry-cli command line tool is the most direct way to upload debug files and underpins the other methods too. Install it via Homebrew with brew install getsentry/tools/sentry-cli, or with the official install script, or as an npm package. You authenticate with an auth token that has project write and release scopes, which you generate in your Sentry account settings under Auth Tokens. Then run a command of the form: sentry-cli debug-files upload --org YOUR_ORG --project YOUR_PROJECT path/to/dSYMs. Point the path at the dSYMs folder inside your .xcarchive, or at your build's derived data dSYM location. The tool scans the directory, extracts the debug identifiers, and uploads each file. You can pass --include-sources if you want Sentry to store source context, and the tool will skip files it has already seen so re-running is cheap. This manual approach is useful for one-off uploads and for understanding what the automated methods do under the hood, but for day-to-day work you will want it wired into your build.
To upload automatically on every build, add a Run Script build phase that invokes sentry-cli. Select your target, open the Build Phases tab, click the plus button, and choose New Run Script Phase. In the script, call sentry-cli debug-files upload using the environment variables Xcode provides, such as DWARF_DSYM_FOLDER_PATH, which points at the dSYMs the current build produced. A typical script exports your org and project, or reads them from a configuration, then runs the upload against that folder. Store your auth token securely rather than hardcoding it in the script that lives in source control; reading it from a local property file or a CI secret is safer. Because dSYM generation happens toward the end of the build, this phase should run after the compile and link steps, which is the default position for a phase you add at the bottom. The advantage of this method is that developers and CI both upload symbols without thinking about it. The caveat is that debug builds without dSYMs will have nothing to send, which the script should handle gracefully.
Sentry also offers higher-level automation. The Sentry Fastlane plugin provides an action, sentry_upload_dsym, that you drop into your Fastlane lane so that dSYM upload happens as part of your existing build and release automation. This is ideal for teams already using Fastlane for signing and App Store submission, because symbol upload becomes just another step alongside gym and deliver. Sentry additionally provides a Cocoa integration and setup wizard that can configure an upload build phase for you, reducing manual scripting. Whichever automation you choose, the goal is the same: guarantee that the exact dSYMs for every shipped build reach Sentry without a human remembering to do it. For App Store builds there is an important wrinkle covered next, but for TestFlight and enterprise distribution, wiring the Fastlane plugin or a build phase into your release pipeline is usually enough to keep symbolication reliable across every version you ship.
There is a specific case that trips up many teams. If you enable Xcode's option to include symbols or if your app went through bitcode processing historically, Apple can recompile your binary on their servers, which produces new dSYMs that differ from the ones your local Archive generated. In that situation the dSYMs you uploaded from your build will not match the crashes coming from App Store users, and symbolication fails. The fix is to download the Apple-generated dSYMs from App Store Connect and upload those to Sentry. In App Store Connect, open your app, select the build, and download the dSYMs, or use Xcode Organizer's Download Debug Symbols action for the archive. Then upload the downloaded files with sentry-cli exactly as you would your own. Because these symbols only exist after Apple processes the build, this step cannot happen at build time; it is a post-submission task. Many teams script it to run once a build finishes processing. If your App Store crashes are unsymbolicated while your TestFlight ones are fine, this recompiled-dSYM mismatch is almost always the cause.
After uploading, confirm Sentry actually has your symbols before you rely on them. In the Sentry dashboard, open your project settings and look for the Debug Files section, sometimes labeled Debug Information Files. It lists every dSYM Sentry has received, each identified by its debug ID and the associated architecture. Match the debug ID against your build; sentry-cli can print the debug IDs of your local dSYMs with the debug-files check or difutil commands so you can compare. When a new crash arrives and a matching dSYM is present, the issue's stack trace shows real function names and line numbers instead of raw addresses. If a crash still shows unsymbolicated frames, the debug ID it needs is listed in the event details, and you can search your Debug Files for that exact ID to see whether it is missing. If you ship frequently, consider adding a lightweight check to your release pipeline that fails loudly when the expected debug ID is absent from Sentry, so a broken upload surfaces at release time rather than during a production incident. Making verification a habit after each release means you discover a broken upload before the crash you actually need to debug comes in, rather than during an incident when readable traces matter most.
For an Archive build, dSYMs live inside the .xcarchive package in a dSYMs folder; find the archive in Xcode Organizer, right-click, Show in Finder, then show package contents. For regular builds, they appear in the build's output directory under Derived Data, at the path Xcode exposes as DWARF_DSYM_FOLDER_PATH.
Apple can recompile your binary during processing, generating new dSYMs that differ from your local ones. The fix is to download the Apple-generated dSYMs from App Store Connect or Xcode Organizer's Download Debug Symbols action, then upload those to Sentry so the debug IDs match the shipped build.
Yes. sentry-cli authenticates with a Sentry auth token that has project write and release scopes. Generate one in your Sentry account settings under Auth Tokens, and keep it out of source control by reading it from a local file or CI secret rather than hardcoding it.
Yes. Add a Run Script build phase that calls sentry-cli against DWARF_DSYM_FOLDER_PATH, or use the Sentry Fastlane plugin's sentry_upload_dsym action in your release lane. For App Store builds, add a post-processing step to upload the recompiled dSYMs Apple generates.
Open your project settings in Sentry and check the Debug Files (Debug Information Files) section, which lists every uploaded dSYM by debug ID and architecture. Compare those IDs against your build's dSYM IDs using sentry-cli. If a crash still shows raw addresses, the event lists the exact debug ID it needs.