Ios – Which iOS app version/build number(s) MUST be incremented upon App Store release


Version/build fields for an iOS app include:

  • "Version" CFBundleShortVersionString (String – iOS, OS X) specifies the release version number of the bundle, which identifies a released iteration of the app. The release version number is a string comprised of three period-separated integers.

  • "Build" CFBundleVersion (String – iOS, OS X) specifies the build version number of the bundle, which identifies an iteration (released or unreleased) of the bundle. The build version number should be a string comprised of three non-negative, period-separated integers with the first integer being greater than zero. The string should only contain numeric (0-9) and period (.) characters. Leading zeros are truncated from each integer and will be ignored (that is, 1.02.3 is equivalent to 1.2.3). This key is not localizable.

  • "iTunes Connect Version Number": version number you specify when creating a new version of the app on iTunes Connect.

My question is:

Which version/build numbers are required to be incremented when a new version of the app is uploaded to iTunes Connect and/or released to the App Store?

Can either "version" CFBundleShortVersionString or "build" CFBundleVersion remain the same between app updates?

Extra points for Apple sources or the exact error messages iTunesConnect displays upon uploading an invalid version/build number.

Android / Google Play note:

The discussion prompting this question is that the public "version" of an Android app in the Google Play Store does not need to be incremented and is in no way validated. The android:versionName can remain the same between releases, upgrade, downgrade, or be any random string rather than something that appears to be a valid "version number".

android:versionName — A string value that represents the release version of the application code, as it should be shown to users.

The value is a string so that you can describe the application version as a <major>.<minor>.<point> string, or as any other type of absolute or relative version identifier.

Difference between versionName and versionNumber in Android

Whereas the android:versionCode is enforced to be an incrementing-on-release integer.

Apple documentation

As noted in the newly accepted answer, Apple has recently published a Technical Note that details their version and build number scheme:

Apple Technical Note TN2420 – Version Numbers and Build Numbers

Best Solution

Apple Technical Note TN2420, Version Numbers and Build Numbers


  • The pair (Version, Build number) must be unique.
    • The sequence is valid: (1.0.1, 12) -> (1.0.1, 13) -> (1.0.2, 13) -> (1.0.2, 14) ...
  • Version (CFBundleShortVersionString) must be in ascending sequential order.
  • Build number (CFBundleVersion) must be in ascending sequential order.

Version Number and Build Number Checklist

Here are some things you can check when submitting a new build to the App Store. Making sure you have your Version Number and Build Number set properly will help you by avoiding having your App automatically rejected for having them improperly configured.

  1. For each new version of your App, you need to invent a new Version Number. This number should be a greater value than the last Version Number that you used. Though you may provide many builds for any particular release of your App, you only need to use one new Version Number for each new release of your App.
  2. You cannot re-use Version Numbers.
  3. For every new build you submit, you will need to invent a new Build Number whose value is greater than the last Build Number you used (for that same version).
  4. You can re-use Build Numbers in different release trains, but you cannot re-use Build Numbers within the same release train. For macOS apps, you cannot re-use build numbers in any release train.

Based on the checklist, the following (Version, Build Number) sequence is valid too.

  • Case: reuse Build Number in different release trains. (NOTE: NOT macOS app)

    (1.0.0, 1) -> (1.0.0, 2) -> ... -> (1.0.0, 11) -> (1.0.1, 1) -> (1.0.1, 2)