Error ITMS-90189 is the "Redundant Binary Upload" error: you uploaded a build whose build number already exists for that version of the app. Despite the common phrasing of the search, it is not actually a bundle-identifier error, that is ITMS-90054, and the two are often confused. The fix is simple: increment your build number (CFBundleVersion) so the binary is unique, then rebuild and re-upload. You do not need to create a new app or change your bundle identifier.
Short answer
ITMS-90189 means "Redundant Binary Upload. There already exists a binary upload with the same build version for that train version." In plain terms, the build number you uploaded is already taken for that app version. It is a duplicate-build-number problem, not the "bundle identifier cannot be changed" error, which is ITMS-90054. The fix is to increment CFBundleVersion, the build number, so it is higher than any previous upload, then rebuild and upload. In Fastlane, increment_build_number does this; in Expo, bump ios.buildNumber. You do not need a new app record.
What ITMS-90189 actually means
ITMS-90189 is App Store Connect refusing your upload because a binary with that build number already exists for the same version. Apple identifies each build by the pair of your version string, the "train" or CFBundleShortVersionString, and your build number, CFBundleVersion, and that pair must be unique. Upload a second binary with the same pair and you get ITMS-90189.
The important thing is that it is about the build number, not the app's identity or code. Nothing is wrong with your bundle identifier, your signing, or your binary's contents; you have simply reused a number that is already on record. That is why the fix is a one-line change rather than a rebuild of your configuration.
ITMS-90189 vs the "bundle identifier cannot be changed" error
Because people search for both together, it helps to separate them clearly. ITMS-90189 is a redundant binary, a duplicate build number. The "bundle identifier cannot be changed from the previous version" message is a different error, ITMS-90054, and it means your CFBundleIdentifier no longer matches the app's registered identifier. They have different causes and different fixes.
The table below sets them side by side.
| Aspect | ITMS-90189 | ITMS-90054 |
|---|---|---|
| Meaning | Redundant binary: build number already used | Bundle identifier changed from previous version |
| Root cause | Duplicate CFBundleVersion for a version | CFBundleIdentifier differs from the app's |
| The fix | Increment the build number and re-upload | Revert the bundle identifier to the original |
| New app record needed? | No | Only if you truly want a new identifier |
| What to change | CFBundleVersion | CFBundleIdentifier |
If your message mentions a redundant binary or an existing build version, you are dealing with 90189 and need to change the build number. If it mentions the bundle identifier changing, you are dealing with 90054 and need to restore the identifier. Fixing the wrong one wastes a cycle.
Why the build number is already taken
The usual reason is simply that you forgot to increment the build number after a previous upload. You uploaded build 1 of version 1.2.0, made a change, and uploaded again without bumping the number, so Apple sees a duplicate. This is easy to do by hand, which is why teams automate it.
A subtler cause is a build number that was consumed by an upload you no longer see as active. A build that is still processing, or one that you rejected or removed, still occupies its number, and you cannot reclaim it. Even a failed or discarded upload counts, so the answer is always to move forward to a new number rather than trying to reuse an old one.
The fix: increment the build number
The fix is to raise CFBundleVersion above the highest number already uploaded for that version, then rebuild and upload. If your last upload was build 3, make the next one build 4. You usually keep the version string the same, because you are shipping another build of the same release, not a new release; only the build number needs to change.
Increment, do not reset. Apple compares against the numbers already on record, so going back down or reusing a number will fail again. As long as each upload's build number is unique and higher within its version, ITMS-90189 will not return.
How to bump the build number in Xcode, Fastlane, and Expo
In Xcode, set the build number in the target's General tab, or the CURRENT_PROJECT_VERSION build setting, to a higher value than your last upload. Apple's agvtool can also increment it from the command line if you prefer working outside the UI.
For automation, let the tool handle it. In Fastlane, the increment_build_number action bumps CFBundleVersion for you, and you can base it on the latest App Store Connect build or your CI run number to guarantee uniqueness. In Expo, raise ios.buildNumber in your app config, or enable autoIncrement in EAS Build so each build gets a fresh number automatically. Whichever path you use, the goal is the same: a build number that is always higher than the last one Apple saw.
Automating unique build numbers in CI
The durable fix is to never set the build number by hand. In CI, derive it from something that always increases, such as the pipeline's run number or a timestamp, so every build is unique by construction. This removes the human step that causes ITMS-90189 in the first place.
Fastlane makes this straightforward, letting you set the build number from the latest App Store Connect build plus one, or from the CI counter. Whatever the source, pin it in your build script rather than the project file, so a developer building locally and a CI job building for release cannot collide. A build number that is generated, not typed, is one you never have to think about again.
Version vs build number: the rule that prevents this
Understanding the two numbers prevents the error entirely. The version string, CFBundleShortVersionString, is the user-facing release name like 1.2.0, and the build number, CFBundleVersion, is the internal counter that must be unique for each upload within a version. ITMS-90189 fires when you keep the version the same, which is fine, but reuse the build number, which is not.
The habit that avoids it is simple: increment the build number for every single upload, including a re-upload after a rejection, and only change the version string when you actually ship a new release to users. Get that rhythm right and redundant-binary errors disappear.
Safe retry path
Follow an ordered path rather than re-uploading the same binary. The checklist below takes you from confirming the cause to a clean upload.
| Step | Action | Why |
|---|---|---|
| 1 | Read the message and note the version and build | Confirms it is a duplicate build number |
| 2 | Increment CFBundleVersion above the last upload | Makes the build unique |
| 3 | Keep the version string the same if not releasing | Only the build number needs to change |
| 4 | In Fastlane, use increment_build_number | Automates the bump |
| 5 | In Expo, bump ios.buildNumber or autoIncrement | Same for EAS builds |
| 6 | Rebuild and re-upload | Produces a unique binary |
The one step that matters most is incrementing the build number above the last upload. Everything else is making sure your tools apply that number consistently, so that a local build and a CI build never resolve to the same value and reintroduce the error.
After upload: scan the build
Clearing ITMS-90189 gets your binary accepted, but acceptance is not security. The redundant-binary check only cares that your build number is unique; it does not look at whether the app ships an embedded secret, allows cleartext traffic, or leaves a debuggable flag enabled. Those issues sail through an upload that has a perfectly good build number.
A scanner like PTKD.com analyzes your .ipa and returns findings ordered by severity and mapped to OWASP MASVS, so you catch security problems before release. To be clear about the boundary: PTKD does not fix ITMS-90189 or manage your build numbers, and it does not replace Apple's validation. It covers the security layer that a build-number check never examines.
What to take away
- ITMS-90189 is the Redundant Binary Upload error: the build number already exists for that version.
- It is not the bundle-identifier error; that is ITMS-90054, with a different cause and fix.
- The fix is to increment CFBundleVersion above your last upload, keeping the version string the same, then re-upload.
- You cannot reuse a build number even from a rejected or removed upload, so always move to a higher number.
- Automate the build number in CI, and scan each accepted build with PTKD.com, because a unique binary is not a secure one.



