Android bundletool failed with error "invalid bundle: duplicate class" troubleshooting
Fixes invalid bundle: duplicate class - Android bundletool in a mobile release pipeline by working through the specific checks and corrections for this failure. Use when this exact error or symptom blocks an archive, upload, review or rollout step. Not for unrelated build failures or for general release planning with no error present.
TL;DR
Remove the duplicated class from one of its two sources: the same library arriving through two dependencies, a jar bundled in libs while also declared in Gradle, or your own class copied into two modules. Print the dependency tree, find both origins of the named class, exclude or delete one, and rebuild. bundletool validates the merged output strictly, so the duplicate must be eliminated at the dependency level, not hidden.
invalid bundle: duplicate class - Android bundletoolUse this when
- bundletool or the release build fails with invalid bundle duplicate class naming a class.
- A dependency was added both as a Gradle dependency and as a local jar or AAR.
- Two libraries shade or embed the same common class.
Not for this skill when
- The duplicate is inside a single prebuilt AAR you cannot modify. Then the fix is excluding the other copy or replacing one library.
- Debug builds show the same duplication. The merge problem is identical; fix it once at the dependency level.
Steps
- Capture the fully qualified class name from the first duplicate class error. Verify: the exact class name is recorded
- Run the Gradle dependencies task for the release runtime classpath and search it for the libraries that could contain that class. Verify: candidate libraries providing the class are listed
- Check the libs folder and any flat file dependencies for jars or AARs duplicating a Gradle dependency. Verify: any double-declared artefact is identified
- Remove the local copy if Gradle already provides it, or add an exclude rule on the transitive dependency that duplicates a library you must keep. Verify: exactly one provider of the class remains in the graph
- Clean and rebuild the bundle. Verify: bundletool validation passes and the AAB is produced
- If the class is your own code copied across modules, move it to a shared module and depend on it from both places. Verify: the class exists in one module in the source tree
- Record the fix in the release runbook or the CI job notes, naming the error, the value or setting that changed, and the date, so the next release engineer does not re-diagnose it from scratch. Verify: the runbook or job notes contain an entry for this error that a teammate can find by searching the error text
Why it happens
Duplicate classes appear when the same bytecode reaches the merger by two routes. Modern dependency graphs make this easy: a library embeds a common utility class instead of depending on it, while another dependency pulls the real artefact. The build tolerated it in some configurations until bundletools whole-program validation flagged the collision.
In practice this failure is rarely a one-off. It tends to recur at the worst point in the release cycle, when a certificate, a toolchain, a store policy or a team process has quietly changed since the last successful release and nobody connected that change to the release pipeline. That is why the steps above insist on reading the actual store, portal or build state at each point instead of trusting configuration files or memory: the configuration usually describes the release the team intended to ship, while this error describes the release the systems actually see. Once the immediate upload or build is unblocked, treat the underlying drift as the real defect. Pin the toolchain version, expiry date, identifier or policy value that caused it in the release checklist, and add the cheapest automatic check that would have caught it before submission day, for example a preflight lane that validates signing, versions and metadata lengths before the full archive runs. A release pipeline that fails in preflight costs minutes; the same failure discovered at submission costs a day.
Variants and edge cases
bundletool duplicate class invalid bundle fix
Tool phrasing; trace both origins via the dependency tree. When you land on this skill from that phrasing, start at step 1 rather than jumping to the most dramatic fix: the early steps are cheap state checks that confirm you are solving the failure you actually have, and they take minutes compared with a rebuild or a store-side change you cannot undo.
duplicate class Android release build two libraries
Graph phrasing for shaded or embedded library classes. When you land on this skill from that phrasing, start at step 1 rather than jumping to the most dramatic fix: the early steps are cheap state checks that confirm you are solving the failure you actually have, and they take minutes compared with a rebuild or a store-side change you cannot undo.
Edge case: test versus main duplicates
A class duplicated only in test source sets does not affect the bundle. Confirm the failing class is in the release runtime classpath. When you land on this skill from that phrasing, start at step 1 rather than jumping to the most dramatic fix: the early steps are cheap state checks that confirm you are solving the failure you actually have, and they take minutes compared with a rebuild or a store-side change you cannot undo.
Provenance
Resolved from the public thread: https://vectle.com/posts/pstulxpPFmfelSkR4PqNYvXg