AGP 9 breaks Flutter Android builds in 2026: what fails and when to upgrade

AGP 9.0 removed KGP support; Flutter 3.44 opts out by default and built-in Kotlin needs Flutter 3.47 or later.

Read time
16 min
Word count
2.5K
Sections
12
FAQs
8
Share
Flutter Android build pipeline diagram showing AGP 9 built-in Kotlin opt-out flags
AGP 9.0 removed Kotlin Gradle Plugin support; Flutter 3.44 opts out by default.
On this page · 12 sections
  1. What AGP 9.0 actually changed
  2. What breaks in a Flutter project specifically
  3. The configuration changes, exactly
  4. Testing AGP 10.0 behaviour before AGP 10.0 ships
  5. What AGP 10.0 removes, and why it decides your sequencing
  6. The two dates that disagree
  7. The upgrade decision
  8. India-specific considerations
  9. A migration checklist that survives contact with a real codebase
  10. FAQ
  11. How eCorpIT can help
  12. References

Summary. Android Gradle plugin 9.0, released as 9.0.1 in January 2026, removed support for applying the Kotlin Gradle Plugin, and that single change is what breaks Flutter Android builds. AGP 9.0 now carries a runtime dependency on KGP 2.2.10, requires Gradle 9.1.0 and JDK 17, and tops out at API level 36.1. Flutter 3.44, the current stable line at 3.44.7, handles this by writing two opt-out flags into your project — android.builtInKotlin=false and android.newDsl=false — so your build keeps working while the ecosystem catches up. The catch that most upgrade posts miss: Flutter's own documentation, updated 5 August 2026, says enabling built-in Kotlin requires Flutter 3.47 or later. On today's stable channel you cannot turn it on at all. Meanwhile Google's two published timelines disagree on when the escape hatch closes: the AGP 9.0 release notes say the opt-out disappears in AGP 10.0 "(mid-2026)", while the AGP roadmap page, last updated 22 July 2026, headlines the same release as "AGP 10.0 (late 2026)". For a team running CI on GitHub-hosted Linux 2-core runners at $0.006 per minute, the cost of this migration is not compute — it is the plugin dependency audit nobody has budgeted for.

This guide covers what actually fails, the exact configuration changes, how to test AGP 10.0 behaviour early, and the timing call for teams shipping production Flutter apps.

What AGP 9.0 actually changed

Two changes in AGP 9.0 matter to Flutter teams, and they are separate.

The first is built-in Kotlin. Before AGP 9.0, an Android module that contained Kotlin source had to apply the Kotlin Android plugin, org.jetbrains.kotlin.android (also written as kotlin-android). AGP 9.0 compiles Kotlin itself and enables that behaviour by default. As the Android build documentation puts it, "Starting with Android Gradle plugin (AGP) 9.0, support for applying the Kotlin Gradle Plugin (KGP) has been removed." Applying it now is not redundant — it is an error.

The second is the DSL. AGP versions 7.x and 8.x still exposed the old DSL types such as BaseExtension, which also implemented the newer public interfaces. AGP 9.0 uses the new interfaces exclusively, and the implementing classes are fully hidden. Access to the old variant API goes with them. If a third-party Gradle plugin in your build still reaches for the old types, you get a specific failure:


            java.lang.ClassCastException: class com.android.build.gradle.internal.dsl.ApplicationExtensionImpl$AgpDecorated_Decorated
cannot be cast to class com.android.build.gradle.BaseExtension
          

Both changes have an opt-out flag, and Flutter sets both for you.

Compatibility floors you cannot negotiate

AGP 9.0's compatibility table is short and strict:

Component Minimum version Default version Practical consequence for Flutter teams
Gradle 9.1.0 9.1.0 A Gradle wrapper upgrade lands before anything else works
SDK Build Tools 36.0.0 36.0.0 CI images pinned to older build-tools need rebuilding
NDK Not applicable 28.2.13676358 Native plugins with pinned NDK versions need a look
JDK 17 17 Build agents still on JDK 11 or 17-only images must move to 17
Max compile SDK API level 36.1 AGP 9.0 will not compile against a higher API level

AGP 9.0 also pulls KGP 2.2.10 as a runtime dependency. You no longer declare a KGP version, and if your build declares one below 2.2.10, Gradle upgrades it automatically. KSP moves to 2.2.10-2.0.2 to match. You can only downgrade KGP if you have opted out of built-in Kotlin, and the floor for a downgrade is KGP 2.0.0.

What breaks in a Flutter project specifically

Flutter's Android tooling sits between your app and AGP, so the failure modes are not identical to a native Android project.

The app's own `build.gradle` breaks first. A Flutter app created before 2026 almost certainly applies kotlin-android in android/app/build.gradle or build.gradle.kts, and sets jvmTarget inside a kotlinOptions block. Under built-in Kotlin, both have to go, replaced by a kotlin { compilerOptions { … } } block.

Plugins break second, and they break harder. A Flutter app pulls in Android build logic from every plugin in its dependency tree. Flutter tracks this in issue #181383, "Flutter plugins should support AGP 9.0.0". Community plugins hit the same wall — wakelock_plus filed issue #117, titled "AGP 9 incompatibility — kotlin-android plugin must be removed". You do not control this code, and a single unmigrated transitive plugin is enough to block the whole build once built-in Kotlin is on.

Add-to-app projects break silently. Flutter's migrator tool writes the two opt-out flags into gradle.properties when you run flutter run or flutter build apk. It cannot do that for an add-to-app Android host, because the host is a pure native Android project and the Flutter tool never runs during its build. Those teams have to add the flags by hand.

KMP modules need a different plugin entirely. If any module applies org.jetbrains.kotlin.multiplatform alongside com.android.library or com.android.application, that combination is no longer compatible with the new DSL. AGP 9.0 introduces com.android.kotlin.multiplatform.library for multiplatform modules, and an app module that mixes KMP with the Android application plugin has to be split into a separate subproject.

The warning you are probably already seeing

Teams that upgraded to Flutter 3.44 report a build-time warning naming every plugin that still applies KGP, with the line that future Flutter versions will fail the build if the app uses such plugins. Treat that warning as your migration backlog. It is the only inventory of your problem that anyone is going to hand you.

The configuration changes, exactly

Flutter's stable default today is the opt-out. Both flags belong in <flutter-project>/android/gradle.properties:


            android.newDsl=false
android.builtInKotlin=false
          

The Flutter migrator adds these automatically on the next flutter run or flutter build apk, and building through Android Studio tooling adds them too. The mechanism is tracked in Flutter issue #183910. Add-to-app hosts get them manually. If your app never applied kotlin-android at all, Flutter's documentation is explicit that you only need android.newDsl=false and no further migration steps.

When you are ready to move off the opt-out, the app-side change is small. Before, in android/app/build.gradle.kts:


            plugins {
    id("com.android.application")
    id("kotlin-android")
    // ...
}

android {
    // ...
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_17.toString()
    }
    // ...
}
          

After, with the plugin and the kotlinOptions block removed and compiler options moved into the kotlin {} block:


            plugins {
    id("com.android.application")
    // ...
}

android {
    // ...
}

kotlin {
    compilerOptions {
        jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
    }
}
          

The Groovy form is the same edit against apply plugin: 'kotlin-android'. An add-to-app host using version catalogs drops alias(libs.plugins.kotlin.android) from its plugins block and makes the same kotlin {} addition.

Then, and only after every plugin in the tree is migrated, flip the flag:


            android.builtInKotlin=true
          

Flutter's version note on that step is the whole timing story: enabling built-in Kotlin requires Flutter 3.47 or later. Stable is 3.44.7 as of the documentation refreshed on 5 August 2026. Setting android.builtInKotlin=true on today's stable channel is not a migration you can complete — it is a migration you can only prepare for.

Testing AGP 10.0 behaviour before AGP 10.0 ships

The useful part of Google's roadmap is that you can enforce the future's strictness on a current AGP 9.x release. Set both flags to true in gradle.properties and your build validates against the API surface AGP 10.0 will require:


            # Enforce modern DSL and Variant API interfaces exclusively
android.newDsl=true

# Enforce built-in Kotlin support without optional opt-out
android.builtInKotlin=true
          

For a large modular codebase, all-or-nothing is impractical, so AGP 9.4.0-alpha04 added per-subproject opt-out:


            android.newDsl=true
android.newDsl.optOut=:lib
          

Google is clear that android.newDsl.optOut is a temporary aid for the 9.x line and disappears with android.newDsl in AGP 10.0. There is a matching module-level control for Kotlin — setting enableKotlin = false inside a module's android {} block removes the Kotlin compiler task for modules with no Kotlin code, which also trims build time and avoids a Kotlin standard library dependency.

For a Flutter app, run this experiment in a branch, not in your release pipeline. The point is to produce the list of plugins that fail, not to ship from it.

What AGP 10.0 removes, and why it decides your sequencing

AGP 10.0 completes a multi-year move to a fully lazy, configuration-cache-compatible build model. The legacy BaseVariant API was eager and task-centric; the androidComponents {} API is lazy and artifact-centric, and removes all references to Task and TaskProvider. The removals are what make this a hard deadline rather than a suggestion:

Removed in AGP 10.0 Replacement Who this hits in a Flutter build
applicationVariants, libraryVariants, testVariants, unitTestVariants androidComponents.onVariants() Custom flavour logic in android/app/build.gradle
variantFilter block androidComponents.beforeVariants() with selectors Teams disabling debug or flavour combinations
android.newDsl, android.builtInKotlin opt-out flags None — flags removed, modern DSL and built-in Kotlin enforced Every Flutter app currently relying on the Flutter-written defaults
Transform API Artifacts API plus AsmClassVisitorFactory Bytecode-rewriting plugins such as older analytics or obfuscation tooling
registerJavaGeneratingTask(), registerResGeneratingTask() variant.sources.java.addGeneratedSourceDirectory(...) Codegen wired into the Android build
sdkDirectory, ndkDirectory, bootClasspath, adbExecutable androidComponents.sdkComponents Custom CI tasks that shell out to adb
buildConfigField(), resValue() eager mutation variant.buildConfigFields.put(...), variant.manifestPlaceholders.put(...) Build-time config injection, very common in Flutter apps with flavours

That last row is the one that catches Flutter teams, because per-flavour buildConfigField entries are how most apps inject API base URLs and environment names into the Android side.

Google's recommended sequence is to fix AGP 9.x deprecation warnings first and reach a state where the build is warning-free without either opt-out flag, then move to 10.0. The AGP Upgrade Assistant in Android Studio (Tools > AGP Upgrade Assistant) automates part of it, and there are agent skills for the upgrade in the Android skills repository and a Kotlin Multiplatform equivalent from JetBrains. Google also runs a global tracking bug for Variant API migration blockers, worth checking before you file anything.

The two dates that disagree

Anyone planning a 2026 roadmap around this hits a documentation conflict, and it is worth naming because the two pages are both official and both current.

Source Page last updated What it says about AGP 10.0
AGP 9.0.1 release notes Current release-notes page for the January 2026 release "The ability to opt-out will be removed in AGP 10.0 (mid-2026)."
AGP DSL/API migration timeline 22 July 2026 Section headed "AGP 10.0 (late 2026)"; timeframes flagged as estimates
JetBrains Kotlin blog 15 May 2026 update Opt-out "will no longer work in AGP 10.0, which is expected sometime in 2026"

The roadmap page carries the later revision date and explicitly labels its timeframes as estimates subject to change, so "late 2026" is the number to plan against. Mid-2026 has already passed without the release, which settles the question in practice. Plan for a release inside 2026 and a Flutter version that supports built-in Kotlin arriving before it.

The upgrade decision

Three positions are defensible right now, depending on what you ship.

Stay on the opt-out and prepare. This is correct for most production Flutter apps in August 2026. Flutter 3.44 already writes the flags, builds pass, and built-in Kotlin cannot be enabled until 3.47 anyway. Use the time to audit plugins and file migration issues upstream.

Test strict mode in a branch now. Correct for teams with heavy custom Gradle logic — flavour matrices, bytecode transforms, generated sources. Those are the AGP 10.0 removals with real engineering behind them, and finding out in a branch costs a week; finding out when the flags disappear costs a release.

Migrate the app-side configuration immediately. Correct for everyone. Removing kotlin-android from your own build.gradle and moving jvmTarget into kotlin { compilerOptions { … } } is a contained edit that is compatible with the opt-out still being in place. There is no reason to carry it.

What is not defensible is doing nothing until Flutter forces the issue. Flutter's own wording is that KGP support was added temporarily "while apps and plugins migrate", and will be removed in a future version. The migration you control is small. The one you do not control — third-party plugins — is the one with the long tail, and it starts with filing issues, which is why Flutter ships a copy-paste issue template for exactly that.

Márton Braun, Kotlin Developer Advocate at JetBrains, put the timing plainly in the Kotlin team's migration post: "We recommend making these configuration changes in your existing projects as soon as possible to ensure smooth upgrades to the latest versions of AGP in the future."

What this costs in CI

The compute cost of the migration is small and worth stating, because it usually gets overestimated. On GitHub-hosted runners, per-minute rates as of August 2026 are $0.006 for Linux 2-core, $0.022 for Linux 8-core, and $0.062 for a macOS 3-core or 4-core runner, with jobs rounded up to the nearest whole minute. Running a parallel strict-mode Android job alongside your existing pipeline roughly doubles the Android leg of the build, not the whole matrix — on a Linux 8-core runner, a 12-minute Android build adds about $0.26 per run. A team merging 20 pull requests a day adds roughly $5.28 a day. The real cost sits in engineering hours spent chasing plugin maintainers, not in runner minutes.

India-specific considerations

Indian product teams and offshore engineering groups carry two extra constraints here.

Build agents are frequently self-managed on cloud VMs rather than GitHub-hosted runners, which means the JDK 17 and Gradle 9.1.0 floors need an image rebuild rather than a config change. That is a platform-team ticket, and it should be raised before the app-side migration, not after.

The plugin tail is also longer for teams shipping India-market apps, because payments, KYC and messaging SDKs are often distributed as Android libraries wrapped in thin Flutter plugins by the vendor. Those wrappers update on the vendor's schedule, not the ecosystem's. If your app depends on a payment gateway plugin, ask the vendor for their AGP 9 built-in Kotlin timeline now, in writing, and put the answer in your release plan. Where those SDKs also handle personal data, the same upgrade window is a reasonable moment to re-check consent and data-handling behaviour against the Digital Personal Data Protection Act 2023, since you are already touching the Android build and its dependency set.

For teams still working through the wider 3.44 upgrade, the Flutter 3.44 production upgrade guide covers the release as a whole, and the related Impeller default rollout on Android and iOS and the CocoaPods sunset and Swift Package Manager migration are the other two forced migrations in the same window. On the platform side, Android 17 API 37 behaviour changes will land in the same planning cycle as AGP 10.0, and the Material UI and Cupertino UI package migration affects the same pubspec.yaml you are already auditing.

A migration checklist that survives contact with a real codebase

  1. Record your current state: Flutter version, AGP version, Gradle wrapper version, JDK on every build agent.
  1. Confirm android.newDsl=false and android.builtInKotlin=false exist in android/gradle.properties; add them by hand for add-to-app hosts.
  1. Remove kotlin-android and the kotlinOptions block from your own module, add kotlin { compilerOptions { jvmTarget = … } }, and confirm the build is unchanged.
  1. Capture the KGP warning output and turn the named plugins into a tracked list.
  1. For each plugin, check its changelog for a built-in Kotlin release; where none exists, file an issue using Flutter's template.
  1. In a branch, set both flags to true and record every failure. Use android.newDsl.optOut for modules you cannot fix yet.
  1. Audit custom Gradle logic against the AGP 10.0 removal table above, replacing applicationVariants with androidComponents.onVariants() and eager buildConfigField calls with variant.buildConfigFields.put(...).
  1. Rebuild CI images for Gradle 9.1.0, SDK Build Tools 36.0.0 and JDK 17.
  1. Re-run the branch experiment monthly; the plugin ecosystem is the variable, not your code.
  1. When Flutter 3.47 or later reaches your channel and the plugin list is clear, flip android.builtInKotlin=true in the main branch.

The real cost here is usually the plugin audit, not the code.

FAQ

How eCorpIT can help

eCorpIT runs Android and Flutter build migrations as a scoped piece of work: a dependency audit that produces the real list of plugins blocking built-in Kotlin, the app-side configuration changes, and a strict-mode CI branch that proves compatibility before the opt-out flags disappear. Our senior engineering teams work to CMMI Level 5 and ISO 27001:2022 practices, which matters when the migration touches payment or KYC SDKs. If your Flutter app is carrying a plugin tail you have not inventoried yet, talk to us about a build-modernisation assessment.

References

  1. Android Gradle plugin 9.0.1 (January 2026) release notes — Android Developers
  1. Android Gradle Plugin DSL/API migration timeline — Android Developers, updated 22 July 2026
  1. Built-in Kotlin migration for app developers — Flutter documentation, updated 5 August 2026
  1. Migrating Flutter Android projects to built-in Kotlin — Flutter documentation
  1. Built-in Kotlin migration for plugin authors — Flutter documentation
  1. Flutter breaking changes index — Flutter documentation
  1. Flutter 3.44.0 release notes — Flutter documentation
  1. Update your Kotlin projects for Android Gradle Plugin 9.0 — Márton Braun, JetBrains
  1. Migrate to built-in Kotlin — Android Developers
  1. Updating multiplatform projects with Android apps to use AGP 9 — Kotlin Multiplatform documentation
  1. Flutter issue #181383: Flutter plugins should support AGP 9.0.0 — flutter/flutter
  1. Flutter issue #183910: add disable built-in Kotlin and new DSL migrators — flutter/flutter
  1. wakelock_plus issue #117: AGP 9 incompatibility — fluttercommunity/wakelock_plus
  1. Android skills repository, AGP 9 upgrade skill — Android
  1. AGP 10.0 Variant API global tracking bug — Google issue tracker
  1. Actions runner pricing — GitHub Docs
  1. Android Gradle plugin 9.4 (preview) release notes — Android Developers

Last updated: 6 August 2026.

Frequently asked

Quick answers.

01 Does AGP 9.0 break every Flutter app immediately?
No. Flutter 3.44 writes android.builtInKotlin=false and android.newDsl=false into gradle.properties automatically when you run flutter run or flutter build apk, so existing builds keep working. Add-to-app Android host projects are the exception, because the Flutter migrator cannot run during a native host build.
02 Why can I not just enable built-in Kotlin today?
Flutter's own documentation states that enabling built-in Kotlin requires Flutter 3.47 or later. The stable channel reflected in that documentation on 5 August 2026 is 3.44.7. Built-in Kotlin also requires AGP 9 or newer, so both the framework version and the build plugin version have to line up first.
03 What error tells me a third-party Gradle plugin is the problem?
A ClassCastException naming ApplicationExtensionImpl$AgpDecorated_Decorated and com.android.build.gradle.BaseExtension means something in your build still references the old DSL types that AGP 9.0 hides. That is usually a third-party plugin rather than your own code, and it needs a version compatible with AGP 9.0.
04 When does the opt-out actually disappear?
Google's two pages disagree. The AGP 9.0 release notes say AGP 10.0 arrives mid-2026, while the AGP roadmap page updated on 22 July 2026 says late 2026 and marks all its timeframes as estimates. Plan against late 2026, since mid-2026 has already passed without the release.
05 How do I test AGP 10.0 compatibility before it ships?
Set android.newDsl=true and android.builtInKotlin=true in gradle.properties on any AGP 9.x release. That enforces the strict API surface AGP 10.0 will require. From AGP 9.4.0-alpha04 you can add android.newDsl.optOut with specific project paths to exclude modules you have not migrated yet.
06 Which Kotlin version does AGP 9.0 use?
AGP 9.0 carries a runtime dependency on Kotlin Gradle Plugin 2.2.10, so you no longer declare a KGP version. Lower declared versions are upgraded automatically and KSP moves to 2.2.10-2.0.2. Downgrading KGP is only possible after opting out of built-in Kotlin, with a floor of KGP 2.0.0.
07 What are the minimum tool versions for AGP 9.0?
Gradle 9.1.0 as both the minimum and default, SDK Build Tools 36.0.0, and JDK 17. The default NDK is 28.2.13676358, and the maximum API level AGP 9.0 supports is 36.1. Self-managed build agents usually need a rebuilt image rather than a configuration change to meet these.
08 Which AGP 10.0 removal is most likely to break a Flutter app?
Eager buildConfigField() and resValue() calls, which AGP 10.0 replaces with variant.buildConfigFields.put(...) and variant.manifestPlaceholders.put(...). Flutter apps that use flavours commonly inject API base URLs and environment names this way, so the change lands squarely in build logic that teams wrote themselves and still maintain today.

About the author

Manu Shukla

Founder & Director

Founder of eCorpIT. Hands-on engineer leading senior-only delivery for AI apps, custom software, and cloud systems for global clients.

Subscribe

One engineering note a week. No fluff, no spam.

Senior-architect playbooks on AI agents, mobile apps, cloud, security, data, and marketing — delivered every Wednesday.

Past the reading

Read enough. Let's build something.

A senior architect responds in 24 working hours with scope, indicative cost, and a timeline. NDA before any technical conversation.