Flutter 'Execution failed for task :app:processDebugResources': Find the Real Error
You run flutter build apk, it churns for a minute, and then it stops on this:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:processDebugResources'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
> Android resource linking failed
You did not touch a single resource file. You changed one line of Dart, or you added a plugin, or you did nothing at all and it worked yesterday. So you paste the error into a search box and get twenty different answers, each swearing that their fix is the one: delete the build folder, invalidate caches, downgrade Gradle, add a theme, change your compile SDK. Some commenter says it fixed it for them. It will not fix it for you, because this error is not one problem.
Execution failed for task ':app:processDebugResources' is a wrapper. It is Gradle telling you the name of the task that died, not the reason it died. The real error is one layer down, produced by AAPT2, the Android Asset Packaging Tool, and Flutter hides it by default. Every minute you spend trying random fixes without reading that underlying message is a minute wasted guessing.
Do not fix processDebugResources directly. Surface the real AAPT2 error first:
flutter build apk --verbose
# or, from the android/ directory:
./gradlew assembleDebug --stacktrace
Scroll up from the failed-task line to the AAPT2 message. It names a file and reason: a missing resource, a malformed XML, or a Support Library plugin clashing with AndroidX. Fix that. On current toolchains, android.enableJetifier=true is no longer the answer; update the offending plugin instead.
Step 1: Make the real error visible
Flutter's default output swallows the Gradle detail. Turn it back on. Two equivalent ways:
# From the project root
flutter build apk --verbose 2>&1 | tee build.log
# Or drop into the Android project directly, which is often cleaner output
cd android
./gradlew assembleDebug --stacktrace --info
Now search the output for the line that AAPT2 actually emitted. It will look like one of these, and this is the text you fix:
error: resource style/Theme.AppCompat.Light.NoActionBar not found.
error: attribute android:requestLegacyExternalStorage not found.
AAPT: error: '@mipmap/ic_launcher' not found.
ERROR: /path/build/.../AndroidManifest.xml:12: AAPT: error: unexpected element <foo> found in <manifest><application>.
That single line tells you which of the completely unrelated root causes you are actually dealing with. Everything below is organised by what that message says.
Cause A: a plugin still on the old Support Library
Message looks like: resource style/Theme.AppCompat... not found, or errors mentioning android.support.* classes. Modern Flutter apps use AndroidX. If a plugin you depend on still references the legacy Android Support Library, its resources and your app's resources cannot link together, and AAPT2 fails.
The advice you will find everywhere is to add android.enableJetifier=true to gradle.properties so Jetifier translates the old library to AndroidX at build time. On current toolchains this advice is stale and can itself break your build. Jetifier is deprecated, and Android Gradle Plugin 8 and 9 no longer support android.enableJetifier or android.useAndroidX=false; AGP 9 treats setting those properties as an error. If your project is on a recent Flutter and AGP, deleting those lines is more likely to help than adding them.
The durable fix is to stop shipping the old library at all:
- Find the offending plugin. The AAPT2 message or the dependency tree names it. Run
./gradlew app:dependencies --configuration debugRuntimeClasspathfromandroid/and look forcom.android.support:*entries. Anything under that group is legacy. - Update it. In
pubspec.yaml, move to a version of the plugin that is AndroidX-native. Most maintained plugins migrated years ago; you are usually pinned to an old one. - If the plugin is abandoned, replace it or fork it. There is no supported way to keep a Support Library plugin alive on AGP 9.
If, and only if, you are on an older AGP (7.x) where Jetifier still works and updating the plugin is genuinely not an option yet, then the legacy pair is android.useAndroidX=true with android.enableJetifier=true in gradle.properties. Treat it as a temporary bridge on old toolchains, not a fix, and note that it disappears the moment you upgrade AGP.
Cause B: a malformed or duplicate resource
Message points at a specific file and line in res/, for example values/colors.xml:8: error: ... or duplicate value for resource 'string/app_name'. This one is mechanical: AAPT2 is telling you exactly where the bad XML is.
- Open the named file at the named line.
- Common offenders: an unescaped
&or<in a string, a colour value missing its#, a duplicate resource name across two files, or a stray element the schema does not allow. - If you recently added an app icon or splash asset, check that the referenced
@mipmap/ic_launcheror@drawable/...actually exists in every density folder it is referenced from.
A frequent Flutter-specific variant: a plugin injects a resource that collides with one of yours, or an icon generator wrote a malformed adaptive-icon XML. The line number is not lying; go read it.
Cause C: the manifest references something that does not exist
Message looks like attribute android:... not found or resource ... referenced from AndroidManifest.xml not found. Your AndroidManifest.xml points at a string, style, or attribute that was never defined, or that requires a higher compile SDK than you are building against.
- Open
android/app/src/main/AndroidManifest.xml. - Find the attribute or resource named in the error. A
@string/...that is not instrings.xml, a@style/...that does not exist, or an attribute likeandroid:requestLegacyExternalStoragethat needscompileSdkVersionraised. - Either define the missing resource, or raise
compileSdkinandroid/app/build.gradleso the newer attribute is known to the compiler. Flutter typically wantscompileSdkto match the highest requirement across your plugins.
Force a version, do not blindly delete plugins
When two plugins drag in conflicting versions of the same Android library and AAPT2 links against the wrong one, the guess-and-remove approach is slow and destructive. Pin the version instead. In android/app/build.gradle:
configurations.all {
resolutionStrategy {
// Force one consistent version instead of letting Gradle pick
force 'androidx.core:core:1.13.1'
}
}
This is surgical: it resolves the specific conflict the dependency tree revealed, without ripping out a plugin you actually need. Use the version the AAPT2 error and ./gradlew app:dependencies point you toward.
Verification
You have fixed the right thing when the underlying AAPT2 message is gone, not just when the wrapper stops appearing on one machine. Prove it:
flutter clean
flutter pub get
flutter build apk --debug --verbose 2>&1 | grep -i "aapt\|resource linking"
A clean build with no AAPT2 lines in the output is the real pass. Then build the variant you actually ship:
flutter build apk --release
If release now succeeds too, the fix was structural. If release still fails on the same task, you fixed a symptom on one variant; go back and read the release build's AAPT2 line, which may differ.
What people get wrong
Treating the task name as the error. Ninety percent of the bad advice for this problem exists because people never read past processDebugResources. The task name is identical for three unrelated bugs, so any fix that ignores the AAPT2 line is a coin flip. Read the line.
Reaching for android.enableJetifier=true in 2026. This was reasonable advice on AGP 7 and earlier. On AGP 8 and 9 it is deprecated to removed, and on AGP 9 setting it can fail the build outright. Copying a five-year-old Stack Overflow answer here actively makes things worse. Update the plugin, do not translate it.
Nuking the build and calling it fixed. flutter clean and deleting ~/.gradle/caches resolves exactly one class of this error: a genuinely corrupt cache. It does nothing for a Support Library conflict or a malformed resource, and when it appears to work it is usually because you changed something else at the same time. If clean fixes it, fine, but confirm the AAPT2 line is actually gone rather than assuming.
When it is still broken
- Bisect your plugins. If you cannot tell which dependency introduced the old library, comment out half your plugins in
pubspec.yaml, build, and narrow down. It is faster than staring at the dependency tree when several plugins are suspect. The same rebuild-and-narrow discipline applies to the React Native version mismatch problem. - Check your Java/JDK and AGP compatibility. A newer AGP needs a newer JDK. A mismatch there can surface as resource-processing failures that look like this one. Run
flutter doctor -vand confirm the Android toolchain is consistent. - Read the full AAPT2 dump with
--info. Some resource failures only print the useful detail at info level. If--stacktracealone is not enough, add--infoand search forAAPT2. - Confirm the resource exists in the merged manifest. Open
build/app/intermediates/merged_manifest/to see what actually got merged from all your plugins. A resource you think you defined may be shadowed or overridden by a plugin's manifest.
Once you are shipping cleanly, the next wall most Flutter teams hit is the store review itself; that is a different kind of umbrella rejection, and I broke it down in why Guideline 2.3.1 rejections are rarely about your text. The pattern is the same as here: the message you are shown is not the message that matters. Read one layer down.
Frequently asked questions
- What does 'Execution failed for task :app:processDebugResources' actually mean?
- It means the Android resource compiler AAPT2 failed while linking your app's resources, but Gradle only shows you the name of the task that failed, not why. It is an umbrella error covering unrelated causes: a plugin on the old Support Library, a malformed XML resource, or a missing resource referenced from the manifest. You must re-run with --stacktrace or --verbose to see the real AAPT2 message.
- How do I see the real error under processDebugResources?
- Run flutter build apk --verbose, or from the android directory run ./gradlew assembleDebug --stacktrace. Scroll up from the task-failed line to find the AAPT2 output, which names the specific file and line, for example 'resource style/Theme.AppCompat not found' or 'error: attribute android:foo not found'. That message, not the task name, is what you fix.
- Is 'android.enableJetifier=true' still the fix for AndroidX conflicts?
- Not on current toolchains. Jetifier is deprecated and Android Gradle Plugin 8 and 9 no longer support android.enableJetifier or android.useAndroidX=false; setting them can now break the build. The durable fix is to update or replace the plugin that still ships the old Support Library so it is AndroidX-native, rather than translating it at build time.
- Why does it say processDebugResources when I am building a release?
- Flutter and Gradle still assemble debug resources as part of many build flows, and plugin or resource problems surface under the debug variant task first. The cause is not that you are in debug mode; it is a resource-linking failure that happens to be reported against the debug resource task. Fix the underlying AAPT2 error and both variants build.