An ITMS-90338 rejection names a symbol your binary should not be touching, and when it points at something like ReachabilitySwift, the cause is almost never your own code. It is a legacy SDK referencing a private Apple API. The work is to find which library carries the flagged symbol, then update or replace it. Here is how to do both.
Short answer
ITMS-90338 means App Store static analysis found your binary referencing a non-public Apple symbol, and the rejection email names the symbol and the framework it sits in. The usual cause is an old or abandoned third-party SDK, such as a dated ReachabilitySwift, rather than code you wrote. Find which library references the symbol with nm or otool, then update or replace that dependency, for example moving from ReachabilitySwift to Apple's Network framework. Because the symbol is compiled into the binary, the fix always ships in a new build.
What you should know
- It is a private-API reference: your binary calls or links a symbol Apple does not publish.
- The email names the symbol: ITMS-90338 lists the exact selector and the framework it was found in.
- The cause is usually a dependency: a static library or SDK carries the symbol, not your own code.
- Legacy networking libraries are common offenders: an old ReachabilitySwift is a frequent example.
- The fix is a new build: the reference is in the binary, so you rebuild after updating or replacing the library.
What does ITMS-90338 actually mean?
It means the App Store's automated check found a reference to a non-public Apple selector in your uploaded binary. Apple runs static analysis at upload, looks for symbol names that match its private APIs, and rejects the build with ITMS-90338 when it finds one, listing the symbol and the binary image it lives in. This is not a runtime test or a human review; it is a name-matching scan over the compiled code. The reference can be a genuine call into a private API, or a symbol whose name happens to collide with a private selector, and the email does not tell you which dependency introduced it. The check runs the same way whether the symbol came from Swift, Objective-C, or a precompiled static library, so the rejection looks identical no matter which language or build system produced the binary.
How do you find which SDK references the symbol?
Search the compiled binary and its frameworks for the flagged symbol. The command-line tools that ship with Xcode list the symbols a binary references, so you can trace the name in the rejection back to a specific library. Start by dumping undefined external symbols:
nm -u MyApp.app/Frameworks/ReachabilitySwift.framework/ReachabilitySwift
Then search a binary or framework for the exact symbol the email named:
nm -Umo MyApp.app/MyApp | grep -i theFlaggedSymbol
The table lists the tools worth knowing.
| Command | What it shows |
|---|---|
| nm -u | The undefined external symbols a binary references |
| nm -Umo | Each symbol with the object or library it belongs to |
| otool -ov | Objective-C class and method structures in the binary |
| strings | Readable strings, including symbol names, inside the binary |
Run these against your app binary and each bundled framework until the flagged symbol shows up, and the framework it appears in is the dependency you need to fix.
How do you fix it once you find it?
Update the offending library, or replace it. If the SDK has a newer release that renamed or removed the symbol, updating the dependency is the fastest fix. If it is unmaintained, replace it with a supported alternative: for reachability specifically, Apple's Network framework and its NWPathMonitor cover network status without a third-party library, which removes the class of problem entirely. If the flagged symbol is your own method that happens to match a private selector, rename your method. After any of these, rebuild and resubmit, because the reference lives in the compiled binary and only a new build clears it. If you manage dependencies with CocoaPods, Swift Package Manager, or a React Native or Flutter plugin, the update happens at the manifest level, and you regenerate the build so the corrected symbols replace the old ones inside the binary.
Is it always a real private-API call, or sometimes a false positive?
It can be either. The check matches symbol names, so a public method or property whose name coincides with a private Apple selector can be flagged even though it never calls a private API. Developers report this kind of collision, and in a genuine false positive you can reply to App Review explaining that the symbol is your own and what it does. The honest caveat is that a reply is slower and less certain than removing the cause, so when the symbol comes from a replaceable dependency, updating or swapping the library is the more reliable path than arguing the false positive. Keep the rejection email either way, because it names the precise symbol you are tracing, and that exact string is what you search for in the steps above.
What to watch out for
The trap is the transitive dependency you did not add directly. A private-API symbol can ride in through a library that one of your other libraries depends on, so the offender may not appear in your own dependency list. Scanning the binary is the reliable way to see what is actually linked, rather than what you think you included. A pre-submission scan such as PTKD.com (https://ptkd.com) reads the compiled APK, AAB, or IPA and reports the SDKs and symbols inside it against OWASP MASVS, which is exactly the legacy-SDK identification this rejection demands, so you can catch a forbidden-API reference before the upload does. The limit is that a scan finds the reference; you still decide whether to update, replace, or rename.
What to take away
- ITMS-90338 means your binary references a non-public Apple symbol, and the rejection email names the symbol and its framework.
- The cause is usually a legacy SDK, such as an old ReachabilitySwift, not your own code.
- Trace the symbol to a library with nm or otool, then update the SDK, replace it (for reachability, use Apple's NWPathMonitor), or rename a colliding method, and rebuild.
- A binary scan such as PTKD.com identifies which bundled SDK carries a forbidden-API reference, including transitive dependencies, before App Store analysis flags it.




