Mr.AndroidShin / Dev Tools

Debugging log · Resources

"AAPT2 error: check logs for details"

This one used to send me straight to a search engine, because the message is almost aggressively unhelpful. "Check logs for details" — which logs? The truth is the real error is right there in the build output; AAPT2 just buries the useful line under a generic headline. Once you know where to look, these are usually a two-minute fix.

The short version: AAPT2 compiles your resources (XML, images, strings.xml, drawables). The "check logs" line is a summary — the actual cause is a more specific error: line a bit above or below it, naming a file and often a line number. Find that line and the fix is usually obvious: malformed XML, an invalid resource name, or a broken image.

The error

ERROR: /path/to/app/src/main/res/values/strings.xml:14:
  AAPT: error: ...
com.android.builder.internal.aapt.v2.Aapt2Exception:
  Android resource compilation failed
Execution failed for task ':app:processDebugResources'.
> AAPT2 error: check logs for details

The bottom line is the headline; the useful part is the error: line at the top with a file path and line:column. Always read upward from "check logs for details".

Step 1 — surface the real message

If the Build window only shows the generic line, expand it. In Android Studio, open the Build tab and click into the failing task to see the full AAPT2 output. From the command line, run with more detail:

./gradlew assembleDebug --stacktrace --info

Look for the first line containing error: and a file path. Everything you need to fix is in that line — the generic summary is just noise.

Common cause 1 — malformed XML

The most frequent culprit. An unclosed tag, a stray character, or an unescaped ampersand in a string will do it:

<!-- ❌ raw & is illegal in XML text -->
<string name="terms">Terms & Conditions</string>

<!-- ✅ escape it -->
<string name="terms">Terms &amp; Conditions</string>

Apostrophes in strings need escaping too (\'), as do a few other characters. If you're hand-editing strings.xml, an escaper saves a lot of these round-trips.

Common cause 2 — an invalid resource file name

Resource file names must be lowercase a–z, 0–9 and underscore, and can't start with a digit. A file like Icon-Home.png or 2x_banner.webp will fail AAPT2. Rename to icon_home.png / banner_2x.webp and update references. The same rule applies to resource IDs inside XML.

Common cause 3 — a broken or unsupported image

A corrupted PNG, a truncated download, or an image in a format AAPT2 doesn't accept in that folder can trigger it. Open the offending file (the path is in the real error line) and confirm it's a valid image; re-export it if in doubt. Malformed vector drawables — a bad pathData string, an unsupported attribute — land here too.

Common cause 4 — a duplicate resource

Defining the same resource name twice (often after a merge, or across values files) produces a "duplicate value" error under the AAPT2 headline. The message names both locations; delete or rename one.

After fixing the underlying file, do a clean build (./gradlew clean) before concluding it's not solved. AAPT2 caches compiled resources, and a stale cache can keep reporting an error you've already fixed. If it truly persists, File → Invalidate Caches / Restart.

If the path points at a library, not your code

Occasionally the failing resource lives in a dependency — usually because a newer library expects a higher compileSdk than your project targets. If the error line points into a cached AAR rather than your res/, bumping compileSdk to match the library's requirement is the usual fix.

Paths and line numbers above are examples — your real error line names the exact file to open.