Flutter: Version Code Has Already Been Used on Google Play? How to Fix It (2026)

By · Published 2026-11-01 · Last verified 2026-11-01

Why does Google Play say the version code has already been used?

Because every Android App Bundle or APK you upload needs a versionCode that Play hasn't seen for that app before, and the one in your file matches an earlier upload. In a Flutter app the version code normally comes from the number after the + in pubspec.yaml: in version: 1.4.0+12, 1.4.0 becomes the versionName users see and 12 becomes the versionCode. Raise the build number (to 13 here), rebuild with flutter build appbundle and upload again. If the number in the bundle still doesn't change, something is overriding it: a hard-coded value in Gradle, a flavor, or a stale build. This guide covers each case, plus a numbering scheme that won't run out, from the routine I use to ship GSPTeck's Flutter apps.

How Flutter turns pubspec into a version code

The Flutter deployment docs describe the version line as three numbers separated by dots, followed by an optional build number after a +. On Android, the build name is used as versionName and the build number as versionCode. Both can be overridden on the command line with --build-name and --build-number. When you rebuild, Flutter writes the values into android/local.properties, and the default app template reads them in android/app/build.gradle (or build.gradle.kts) as flutter.versionCode and flutter.versionName.

Four steps from pubspec version 1.4.2+57 to Flutter build-name and build-number, Gradle versionName and versionCode, and Play requiring a new, higher code
From pubspec to Play.

Android's own documentation explains why Play is strict: versionCode is a positive integer used as an internal version number, Android uses it to stop users installing a lower version over a higher one, and you can't upload an APK to the Play Store with a version code you've already used for a previous version. The greatest value Google Play allows is 2100000000.

Five reasons the version code didn't change

  1. You changed the version name, not the build number. Going from 1.4.0+12 to 1.4.1+12 changes what users see, but the version code is still 12. Bump the number after the +.
  2. The code was already used on another track. Internal testing, closed testing, open testing and production are tracks of the same app, so a build number used for a test upload is taken for production too. Check the App bundle explorer in Play Console for the highest code you've uploaded, and go above it.
  3. Gradle hard-codes the value. Older projects, or ones edited by hand, may have versionCode 1 instead of flutter.versionCode in defaultConfig. Then pubspec changes are ignored. Restore the Flutter value or manage it in one place on purpose.
  4. A product flavor overrides it. Android lets flavors set their own versionCode, and that wins over defaultConfig. If you build with --flavor, check the flavor block.
  5. CI passes an old number. A pipeline that runs flutter build appbundle --build-number=$SOMETHING overrides pubspec. If that variable resets, for example because the pipeline was recreated, it will reuse codes. Make the CI number start above the highest code already on Play.
Grid of reasons the version code didn't change: not bumped, used on another track, hard-coded in Gradle, a flavor override, a CI build number and codes used before
Why the code didn't change.

The quick fix, step by step

  1. In Play Console, open the App bundle explorer and note the highest version code listed for the app.
  2. In pubspec.yaml, set the number after the + to one more than that. Keep the version name as it is unless you want users to see a new version.
  3. Run flutter clean if you've changed flavors or Gradle files recently, then flutter build appbundle (add --flavor if you use one).
  4. Open android/local.properties and check that flutter.versionCode now shows the new number.
  5. Upload the new .aab from build/app/outputs/bundle/release/ to the same release, replacing the rejected one.

If the error comes back with the same number, go through the five causes above; one of them is overriding your pubspec.

Check the bundle before you upload it

A quick check saves a failed upload. After building, open android/local.properties and confirm flutter.versionCode is the number you expect. Android merges the version values into the app's manifest at build time, so the bundle carries whatever Gradle resolved, not what pubspec says in isolation. In Play Console, each bundle you add to a release is listed with its version code, so compare it with the App bundle explorer before you roll out.

Four steps of the quick fix: find the highest code in the App bundle explorer, bump the build number, build the app bundle and check local.properties
The quick fix.

A numbering scheme that won't trip you up

Android's docs suggest starting at 1 and increasing the version code with every release, whatever the size of the release. In practice, pick one source of truth and stick to it:

Whatever you choose, don't jump far ahead "just in case". A code can't go back down, and the 2100000000 ceiling is real. If you're also changing signing, keep the versioning change separate; our notes on resetting a lost upload key cover that path.

One more distinction helps when you plan numbers. The version code is for Android and Play only; Android's documentation says it doesn't need to resemble the release version users see, and that apps and publishing services shouldn't display it to users. So there's no reason to make the two match. A version name of 2.0.0 with a version code of 57 is perfectly normal, and it keeps you free to bump the code as often as you upload without changing what users read in the store.

Two columns: versionName is shown to users and can be any string, versionCode is an integer up to 2100000000 that must rise with every upload
Version name vs version code.

Where this shows up in a normal release

Most duplicate-code errors happen in the busy days around a release: a quick fix uploaded to internal testing, then the "real" build reusing the same number. Bumping the build number is the first line of my Flutter and Firebase release checklist for Google Play. If you're shipping a new app, the same applies to every build you upload during closed testing with 12 testers for 14 days. When a build goes to production gradually, each fix during a staged rollout needs a new, higher code too. For this year's Android 16 changes in one place, see the Flutter Android 16 upgrade hub.

Vertical Pinterest graphic with five points on fixing a Flutter version code already used on Google Play
Pinterest pin: version code already used.

FAQ

Where is the versionCode in a Flutter app?

It's the number after the + in the version line of pubspec.yaml. Flutter writes it to android/local.properties as flutter.versionCode, and the default Gradle file reads it from there. You can override it with flutter build appbundle --build-number.

Can I reuse a version code if I deleted the release?

Plan on no. Android's documentation says you can't upload an APK with a version code already used for a previous version, so treat every uploaded code as taken and simply use the next number.

What is the maximum versionCode on Google Play?

Android's versioning documentation gives 2100000000 as the greatest value Google Play allows. Date-based schemes like yyyymmdd plus a two-digit counter stay under it.

Do I need to change the version name too?

No. Play only requires a new, higher versionCode. The versionName is the label users see, so change it when you want users to see a new version number.

Sources