Android Resource Linking Failed (AAPT2): Find the First Real Error
Android resource linking failed is usually the wrapper, not the diagnosis. AAPT2 has distinct compile and link phases, and the Gradle task can surface diagnostics from resource compilation, merging, manifest processing or final linking. In the same failing task, find the earliest actionable diagnostic that names a resource, attribute, XML/manifest file, line or platform symbol. Classify that evidence first; later wrapper/linking messages are often consequences.
Android resource linking failed or Aapt2Exception.A nearby line says resource ... not found, attribute ... not found, unknown element, or names an XML file and line.The failure occurs in the Android resource/manifest pipeline; confirm whether the concrete diagnostic belongs to AAPT2 compile, merge/manifest processing, or link before applying a linking-specific fix.resource drawable/color/string/style/... not found →Prove whether that exact resource exists in the active source set or dependency.XML file + line / unknown element →Fix the exact XML, nesting, resource declaration or reference at that location.attribute ... not found / missing theme style →Separate your own resource mistake from a missing/incompatible library or theme.android:attr/... not found →Check the Android platform API exposed by compileSdk and the dependency that requires it.Error points into merged/generated resources or an AAR →Trace which source set or dependency contributed the failing resource before editing generated files.Headline only; no useful line visible →Expand Build Output or rerun the failing Gradle task with enough output to capture the first AAPT2 error.Open the same failed Gradle task and scroll above the generic Android resource linking failed wrapper. Capture the earliest actionable AAPT2/resource diagnostic that identifies a file, line number, resource, style, attribute or manifest problem. Do not rely only on the first literal line containing error:; earlier tool output can contain the evidence that caused the later wrapper.
app/src/main/res/layout/activity_profile.xml:22: error:
resource drawable/ic_profile not foundVerify: You can state the failure without saying only “AAPT2 failed”—for example, “drawable/ic_profile is not found” or “android:attr/... is not found.” That concrete line chooses the branch below.
Why the first concrete error matters
Android documents AAPT2 as a two-stage resource tool: compile processes individual resource files into intermediate output, while link consumes compiled resources plus the manifest/platform inputs to produce packaged resource output. Gradle also performs resource merging and manifest work around that pipeline. Therefore a final linking wrapper can sit on top of an earlier compile/merge/manifest diagnostic. Preserve the phase named by the concrete failure instead of calling every XML/resource problem a link failure.
A missing drawable is a different investigation from a missing Android framework attribute.
Your source file, merged output and dependency resources imply different owners.
If later errors disappear, they were downstream symptoms. If a new first error appears, treat it as new evidence.
Fix #2 — resource ... not found: prove the exact resource exists
If AAPT2 names drawable/foo, color/foo, string/foo, style/Foo or another app resource, start with that exact type and name. Confirm the reference spelling, the resource declaration/file, and whether it belongs to the source set or build variant you are actually building.
Android resource merging can draw from the main source set, build variants and Android libraries. A file existing somewhere in the repository does not prove it participates in the current variant.
Verify: Rebuild the same variant. The original exact resource ... not found line should be gone. If the build stops at a different concrete resource, follow that new line rather than continuing to change the first resource.
Fix #3 — file + line / unknown element: repair the XML or declaration there
When AAPT2 gives a source file and line, inspect that location before changing Gradle—but treat the line number as a starting point, not always the root cause. A malformed opening tag, missing quote, bad namespace, or invalid parent element earlier in the same XML can make the parser complain on a later line. Read several lines above and below the reported location and check malformed XML, incorrect nesting, wrong namespace/reference syntax, invalid resource declarations, and duplicated or misplaced elements.
Android's AAPT2 documentation gives a concrete example: a misplaced <action> element in AndroidManifest.xml produces unknown element <action> found. It also documents resource-declaration syntax that older AAPT behavior could tolerate but AAPT2 rejects.
build/ as the durable fix. If the reported path is merged/generated output, use it as evidence and trace the contributing source or dependency instead.Verify: The same source location no longer produces the first AAPT2 error after rebuilding the same variant.
Fix #4 — attribute ... not found or missing theme/style
First decide who should provide the missing symbol. A custom attribute may belong to your app or a library. A theme/style may require a dependency that is missing from the active module or may have been renamed during a migration.
Do not immediately raise compileSdk for every missing attribute. If the missing name is your app/library namespace, prove the declaration or dependency first. If it is explicitly an Android framework attribute—android:attr/...—use the next branch.
Verify: The expected provider is present in the active build and the original attribute/style name resolves without inventing a dummy resource.
Fix #5 — android:attr/... not found: check the platform/dependency boundary
AAPT2 links Android-namespaced resources against the platform android.jar selected by your module's compileSdk. If a dependency references android:attr/foo and that platform does not contain the attribute, the linker cannot resolve it. First confirm the missing symbol really begins with android:attr/; then identify which dependency or resource introduced it and compare that requirement with the module's compileSdk and installed platform.
compileSdk determines which Android platform APIs/resources are available while compiling/linking. minSdk declares the minimum API level on which the app is intended to run/install. Raising minSdk does not add a missing framework attribute to the android.jar used by AAPT2. Do not blindly raise either value or downgrade random libraries: make the smallest compatible change supported by the dependency, Android Gradle Plugin and installed SDK.Verify: The selected compile platform and dependency set are mutually supported, and the exact android:attr/... linker error disappears.
Fix #6 — merged/generated/AAR resource: find the owner before editing
If the path points into build/intermediates, merged resources, or values contributed by an AAR, do not patch that generated file. Trace the failing symbol back to its owner. Android resource merging uses source-set priority, but real projects can include variant-specific source sets, build types, one or more product flavors/flavor dimensions, main, and library resources. Do not reduce a multi-flavor build to one universal linear list: inspect the active variant's merged-resource inputs and merge result to determine which declaration won or which provider is absent. App/project resources can override library resources according to merge priority, so the same symbol can resolve differently across variants.
Useful questions: Did the failure start after adding/upgrading a library? Does only one flavor/build type fail? Is the expected resource present only in another variant? Did a dependency/theme migration remove the provider?
Verify: Rebuild from source and confirm the generated/merged output is now correct without hand-editing anything under build/.
What not to do
Android resource linking failed itself as the root cause; capture the first concrete AAPT2 line.Do not start with Invalidate Caches, deleting Gradle caches, or repeated Clean/Rebuild when the output already names a deterministic resource error.Do not create fake resources merely to silence a missing dependency/theme symbol.Do not edit merged/generated files under build/.Do not change compileSdk, minSdk, AGP and dependency versions all at once; you lose the evidence of which compatibility boundary mattered.Do not download replacement AARs or build tools from unofficial sources to bypass a linker error.Do not label every failure ending in “Android resource linking failed” as an AAPT2 link-stage root cause; preserve whether the earliest concrete failure occurred during compile, merge/manifest processing, or link.Do not assume a single source-set precedence list describes every multi-flavor project; inspect the active variant's actual merged inputs/output.Do not choose the first literal “error:” line mechanically when an earlier actionable resource diagnostic in the same failed task explains the cascade.Do not keep diagnosing the old resource once the same task advances to a different concrete error or a later build stage.Still seeing Android resource linking failed?
If Android Studio shows only a wrapper such as Aapt2Exception, Execution failed for task ...process...Resources, or the final Android resource linking failed line, open detailed output and expand the same failed resource-processing task. Search upward for the earliest actionable resource diagnostic—often a line naming a resource, attribute, XML/manifest file or line number. Do not mechanically select the first literal error: if an earlier AAPT2/merge/manifest diagnostic explains it.
If the IDE still hides it, rerun the same failing Gradle task shown in the error from the project root instead of guessing another task. Add --info if normal output is too terse; use --stacktrace when you also need the Gradle exception chain. The goal is not a longer log—the goal is the earliest concrete AAPT2 diagnostic before the wrapper. If fixing that resource reveals a different first error, that is progress: classify the new line again.
./gradlew :app:<the-failing-resource-task> --info
# add --stacktrace if the Gradle exception chain is also neededprocessDebugResources command if your failing task is different. On Windows, invoke the Gradle wrapper appropriate for your shell.Official references
Still stuck? Ask the community
Share the first concrete AAPT2 line, module/variant, compileSdk, AGP version and the smallest relevant XML/resource snippet. The generic headline alone usually is not enough.
Loading community discussion…
Comments could not load here. Open ErrorHarbor Discussions on GitHub →