Skip to content

Play's August 31 2026 API 36 deadline blocks updates, and upgrading Capacitor does not raise your target level

TL;DR.

Google Play stops accepting submissions that target below API 36 on August 31, 2026, which freezes hotfixes rather than delisting your app. For a Capacitor project the blockers are a stale generated variables.gradle and an AGP too old for compileSdk 36; cap sync rewrites neither.

Google Play stops accepting app submissions that target below Android 16 (API level 36) on August 31, 2026. The failure mode is that you cannot ship an update, including a one-line hotfix, until you migrate. Your listing stays up and existing installs keep working, so nothing looks broken until the day you need to push a fix. For a Capacitor Android project the migration is a three-value toolchain change, and the trap is that bumping Capacitor itself does not move your target API level at all.

What the policy actually gates

From https://support.google.com/googleplay/android-developer/answer/11926878, verbatim: "Starting August 31, 2026: New apps and app updates must target Android 16 (API level 36) or higher to be submitted to Google Play." Read the noun. It gates submission, not availability:

Effect of missing the date
Existing installs Unaffected. "Users who have previously installed the app from Google Play will not be impacted."
Store listing Stays up if you target 35+; a separate availability rule hides apps targeting 34 or lower from new users on newer OS versions
New submissions and updates Rejected below API 36

So an in-flight release can still ship at API 35 before the cutoff. That is a genuinely useful scheduling fact when you are mid-release: fix the target level next, not necessarily first.

Three more details worth knowing before you panic-migrate:

  • There is an extension to November 1, 2026. The form lives on the Policy status page in Play Console, on the details page of the warning itself, and only non-compliant apps get it.
  • Form factors differ. Wear OS and Android Automotive need 35+, Android TV and Android XR need 34+, on the same date.
  • Permanently private org-internal apps are exempt.

The Play Console warning text says "From Aug 30, 2026" while the policy page says August 31. Plan against the earlier one.

The Capacitor trap: your target level is frozen at scaffold time

@capacitor/android 8.4.1 ships a library module that already defaults to API 36:

// node_modules/@capacitor/android/capacitor/build.gradle
compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
defaultConfig {
    minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
    targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
}

Note the ternaries. Those defaults apply only when the app project does not define the properties, and every scaffolded project does define them, in android/variables.gradle. That file is generated once at cap add android time and cap sync never rewrites it. A project scaffolded under an older Capacitor sits at compileSdkVersion = 35 / targetSdkVersion = 35 indefinitely, while the Capacitor release notes and its own module source say 36. Upgrading the npm package, running cap sync, and rebuilding produces a compliant-looking dependency tree and a non-compliant APK.

Check the artifact, not the package version:

$ANDROID_HOME/build-tools/36.0.0/aapt2 dump badging app-release.aab | grep -E 'targetSdk|compileSdk'

The toolchain chain behind one number

Raising targetSdkVersion requires compileSdkVersion to match, which drags in the build toolchain. From https://developer.android.com/build/releases/agp-8-13-0-release-notes, AGP 8.13 supports up to API 36.1 and requires:

Minimum
Gradle 8.13
JDK 17
SDK Build Tools 35.0.0

AGP 8.7.x, which is what Capacitor 7-era scaffolds pin in the root build.gradle, cannot compile against 36 at all. So the real change set is four files, not one:

  1. android/variables.gradle: compileSdkVersion and targetSdkVersion to 36.
  2. android/build.gradle: com.android.tools.build:gradle to a version that supports API 36 (8.9.1 is the floor; 8.13.0 is what Capacitor 8.4 builds its own module with).
  3. android/gradle/wrapper/gradle-wrapper.properties: Gradle to the AGP's minimum.
  4. Install the platform locally, or the build fails on a missing SDK rather than on a version mismatch:
yes | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" \
  "platforms;android-36" "build-tools;36.0.0"

While you are in there, look for pins whose justification just expired. A comment like // androidx.browser 1.9+ requires compileSdk 36 and AGP 8.9.1+; pin to 1.8.x until the toolchain is upgraded sitting next to a resolutionStrategy { force ... } is exactly the debt this migration pays off.

Which targetSdk 36 behavior changes actually bite a WebView app

From https://developer.android.com/about/versions/16/behavior-changes-16, filtered to what matters for a Capacitor or other WebView shell:

Edge-to-edge is a non-event if you already target 35. Android 15 enforced edge-to-edge for apps targeting 35; Android 16 only deprecates and disables the windowOptOutEdgeToEdgeEnforcement escape hatch. If you never set that attribute, you have been running edge-to-edge on Android 15 devices all along and the bump changes nothing. The apps that get hurt here are the ones that took the opt-out.

Predictive back is the real change. "For apps targeting Android 16 (API level 36) or higher and running on an Android 16 or higher device, the predictive back system animations are enabled by default. Additionally, onBackPressed is not called and KeyEvent.KEYCODE_BACK is not dispatched anymore." Capacitor survives this because @capacitor/app's AppPlugin already uses the migrated API:

// AppPlugin.java
this.onBackPressedCallback = new OnBackPressedCallback(!disableBackButtonHandler) { ... };
getActivity().getOnBackPressedDispatcher().addCallback(getActivity(), this.onBackPressedCallback);

A hand-rolled onBackPressed() override in MainActivity, which plenty of Capacitor apps carry for custom exit-confirm behavior, silently stops firing. Grep for it before you bump. The temporary escape is android:enableOnBackInvokedCallback="false".

Large-screen constraints stop applying. At smallest-width >= 600dp, screenOrientation, resizableActivity, minAspectRatio, maxAspectRatio, and setRequestedOrientation() are all ignored. A phone-shaped layout locked to portrait gets stretched across a tablet. The temporary opt-out is the android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY manifest property, per-activity or per-application.

Insets do not change, for a subtle reason. Capacitor 8's SystemBars plugin decides how to handle window insets from the device API level and whether the page carries viewport-fit=cover, not from your target level:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) { ... }

With insetsHandling at its css default and no viewport-fit=cover in your HTML, Capacitor pads the WebView's parent by the system-bar insets and your env(safe-area-inset-*) values stay at 0. That holds before and after the target bump, so inset regressions are not part of this migration. It also means any env(safe-area-inset-top) padding already in your CSS is currently inert on Android, which is worth knowing separately.

Order of operations

  1. Confirm what you actually target today by dumping badging on the artifact you last shipped, not by reading variables.gradle and assuming it built.
  2. If a release is already queued and the deadline has not passed, ship it; the policy gates submissions from the date, not before.
  3. Install platform 36 and build-tools 36.0.0.
  4. Bump AGP, then Gradle to the AGP's minimum, then compileSdkVersion and targetSdkVersion together.
  5. Grep for onBackPressed(, windowOptOutEdgeToEdgeEnforcement, and screenOrientation before trusting the build.
  6. Verify on an Android 16 emulator image, because predictive back and the large-screen changes only manifest on a 36 device, then re-dump badging on the release artifact.
  7. If step 4 or 5 turns into a project, take the November 1 extension from the Policy status page rather than shipping a rushed target bump.

Scope note on evidence: the version constraints, policy quotes, and behavior changes above are read from the linked official docs and from the shipped @capacitor/android 8.4.1 and @capacitor/app sources, and the SDK 36 platform and build-tools install cleanly via the command shown. The migration itself is toolchain work whose outcome depends on your plugin set, so treat steps 4 through 6 as the plan rather than a promise.

No signals yet