Quick answer: Read the actual Java exception in the Unity Console (expand the Gradle error output fully), then fix the specific cause: raise Minimum API Level in Player Settings to satisfy plugin requirements, add exclude rules for duplicate classes in mainTemplate.gradle, or install the exact NDK version Unity requires via Android Studio’s SDK Manager.
Unity’s Android build pipeline wraps a full Gradle build, and when Gradle fails, Unity surfaces a one-line error that hides the real Java exception three scrolls below it in the Console. The result is that developers spend hours Googling the Unity error message when the actual fix is in the hidden Gradle output. This guide covers every common Gradle failure mode in Unity 2023 and later, starting with how to read the actual error so you can stop guessing.
The Symptom
The build bar reaches roughly 90%, then Unity prints something like CommandInvokationFailure: Gradle build failed. in the Console, followed by a wall of Java stack trace that is easy to dismiss. The apk or aab is not produced. The error message Unity highlights is rarely the root cause — it is the Gradle wrapper reporting that a subprocess exited with a non-zero code. The actual exception is buried in that wall of text, often starting with FAILURE: Build failed with an exception and then * What went wrong:.
Expand the Console error fully by clicking the triangle, or find the full log in Temp/gradleOut/ inside your Unity project folder. The file gradle_build.log there contains everything Gradle printed, untruncated.
What Causes This
minSdkVersion conflict. Every Android plugin can declare a minimum SDK version in its AndroidManifest.xml or build.gradle. If any plugin requires, say, API 26 and your Unity Player Settings has Minimum API Level set to API 22, Gradle refuses to merge the manifests. The error reads: uses-sdk:minSdkVersion 22 cannot be smaller than version 26 declared in library. Fix: raise the Unity minimum API level to match or exceed the highest value any plugin demands. Check Edit > Project Settings > Player > Android > Minimum API Level.
Duplicate class errors. Two plugins that both depend on a common library (Firebase, OkHttp, Kotlin stdlib) will each bundle their own copy of its classes inside their AARs. Gradle sees the same fully-qualified class name twice and aborts. The error reads: Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules... or similar. This has become more common as Unity plugin authors have stopped relying on Google’s Play Services Resolver.
NDK not installed or wrong version. If your game uses native code (C++ plugins, IL2CPP) Unity specifies an exact NDK version in Project Settings > Player > Android > Android NDK Path. If that path is empty or points to a version that does not match what Unity expects, the build fails with Unable to list target platforms. Please make sure the android sdk path is correct or an NDK-related CMake error. Unity 2023 requires NDK r23c by default for IL2CPP builds.
Custom Gradle templates out of sync. When you enable Custom Main Gradle Template or Custom Gradle Properties Template in Player Settings, Unity writes template files to Assets/Plugins/Android/. These templates are version-specific. Upgrading Unity without regenerating the templates leaves the old Gradle DSL syntax in place, which newer Gradle versions reject. Look for errors mentioning Could not find method android() or Unresolved reference: implementation.
The Fix
Fixing duplicate classes. Add an exclusion rule in your mainTemplate.gradle. Enable Custom Main Gradle Template in Player Settings, then open Assets/Plugins/Android/mainTemplate.gradle and add an exclude inside the offending dependency:
// mainTemplate.gradle — exclude duplicate Kotlin stdlib from a plugin
dependencies {
implementation('com.example.plugin:analytics-sdk:2.3.1') {
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
}
// Let Unity's own Kotlin dependency win
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22'
**DEPS**
}
The **DEPS** token is Unity’s placeholder — leave it in place. Unity replaces it with auto-generated dependency entries during the build.
Fixing NDK issues. Open Android Studio, go to SDK Manager > SDK Tools > NDK (Side by side), and install the version Unity requires. Then set the path in Project Settings > Player > Android > Android NDK. You can also let Unity manage the NDK automatically by leaving the field blank — Unity downloads the correct version if the Android Build Support module was installed with the correct sub-components via Unity Hub.
Regenerating Gradle templates. If you suspect stale templates, the safest fix is to delete the custom template files from Assets/Plugins/Android/, uncheck the custom template options in Player Settings, then re-enable them. Unity regenerates fresh templates matched to your current Unity version. Diff the old and new files to see what changed before deleting your customizations.
“Always read the Gradle build log in
Temp/gradleOut/gradle_build.lograther than the Unity Console. Unity truncates the output; Gradle does not. The actual root cause is almost always in the last 30 lines of that file.”
Exporting the Gradle Project for Isolated Debugging
The most powerful debugging move for persistent Gradle errors is to export the Gradle project and build it independently. Go to File > Build Settings, enable Export Project, and click Export. Unity writes the full Gradle project to a folder on disk. Open a terminal in that folder and run:
// These are shell commands, not C# — run in a terminal
// On macOS / Linux:
./gradlew assembleDebug --stacktrace
// On Windows:
gradlew.bat assembleDebug --stacktrace
The --stacktrace flag prints every Gradle exception with its full Java stack. You can now fix the Gradle files directly and run the build again without touching Unity, which is dramatically faster than a full Unity build cycle. Once the standalone Gradle build succeeds, copy your template changes back into Assets/Plugins/Android/.
gradleTemplate.properties and Heap Size
Large projects with many plugins exhaust the Gradle JVM heap, producing a build failure with OutOfMemoryError: Java heap space. Enable Custom Gradle Properties Template in Player Settings and edit Assets/Plugins/Android/gradleTemplate.properties:
# gradleTemplate.properties
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g
org.gradle.daemon=true
org.gradle.parallel=true
android.useAndroidX=true
android.enableJetifier=true
-Xmx4g raises the JVM heap to 4 GB. android.enableJetifier=true automatically converts legacy Support Library references to AndroidX, which resolves a whole class of compatibility errors when mixing old and new plugins.
Related Issues
If the Gradle build succeeds but the app crashes immediately on launch, the issue is typically a missing permission in AndroidManifest.xml, an IL2CPP stripping issue removing a class your plugin needs at runtime, or a 32-bit vs. 64-bit ABI mismatch. The Google Play Console now requires 64-bit support — ensure Target Architectures in Player Settings includes ARM64. For runtime crashes on Android, attach a crash reporter so you receive the logcat output and stack trace automatically rather than waiting for a user to paste it into a forum post.
Gradle errors are the kind of build-time failure that blocks your whole team — adding a Bugnet build webhook means everyone gets notified the moment a CI build fails, not when someone notices the nightly build folder is empty.