App Store

    Error ITMS-90189: Redundant Binary Upload (Fixed)

    App Store Connect showing an ITMS-90189 Redundant Binary Upload error next to the build number field.

    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.

    AspectITMS-90189ITMS-90054
    MeaningRedundant binary: build number already usedBundle identifier changed from previous version
    Root causeDuplicate CFBundleVersion for a versionCFBundleIdentifier differs from the app's
    The fixIncrement the build number and re-uploadRevert the bundle identifier to the original
    New app record needed?NoOnly if you truly want a new identifier
    What to changeCFBundleVersionCFBundleIdentifier

    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.

    StepActionWhy
    1Read the message and note the version and buildConfirms it is a duplicate build number
    2Increment CFBundleVersion above the last uploadMakes the build unique
    3Keep the version string the same if not releasingOnly the build number needs to change
    4In Fastlane, use increment_build_numberAutomates the bump
    5In Expo, bump ios.buildNumber or autoIncrementSame for EAS builds
    6Rebuild and re-uploadProduces 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.
    • #itms-90189
    • #redundant binary upload
    • #build number
    • #app store connect
    • #ci cd

    Frequently asked questions

    What does ITMS-90189 mean?
    It is the Redundant Binary Upload error. It means you uploaded a build whose build number already exists for that version of the app, because Apple requires the pair of version string and build number to be unique. It is not a code or signing problem; you simply reused a build number, and the fix is to increment it.
    Is ITMS-90189 a bundle identifier error?
    No. Despite the common search phrasing, ITMS-90189 is about a duplicate build number, not the bundle identifier. The bundle identifier cannot be changed message is a separate error, ITMS-90054. If your message mentions a redundant binary or an existing build version, it is 90189, and you fix it by changing the build number.
    How do I fix ITMS-90189?
    Increment your build number, CFBundleVersion, so it is higher than any build already uploaded for that version, then rebuild and re-upload. Keep the version string the same if you are not shipping a new release. You do not need to change your bundle identifier or create a new app record.
    Can I reuse a build number if the previous build was rejected?
    No. A build number is consumed once uploaded, even if that build was rejected, removed, or is still processing. You cannot reclaim it, so always move forward to a higher build number. Trying to reuse a number will trigger ITMS-90189 again.
    How do I auto-increment the build number in Fastlane or Expo?
    In Fastlane, the increment_build_number action bumps CFBundleVersion, and you can base it on the latest App Store Connect build or your CI run number. In Expo, raise ios.buildNumber in your app config or enable autoIncrement in EAS Build. Deriving it from a CI counter guarantees a unique number every time.
    Does a unique build number make my app secure?
    No. A build number is bookkeeping; it says nothing about security. A build that uploads cleanly can still contain embedded secrets or insecure settings. Scan it with a tool like PTKD.com (https://ptkd.com) for these issues, mapped to OWASP MASVS, so an accepted build is also a secure one.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free