You have just upgraded Flutter, Android Studio, or your JDK, and your build pipeline has halted with a stack trace resembling this:
java.lang.IllegalArgumentException: Unsupported class file major version 61
Or perhaps version 65.
This is not a cryptic bytecode error; it is a rigid version mismatch. In the Java ecosystem, class file major versions correspond to specific JDK releases:
- 61 = Java 17
- 65 = Java 21
This error occurs when a build tool (specifically Gradle) running on an older JVM attempts to read classes compiled by a newer JDK, or when the Gradle version defined in your project is too old to support the JDK version you are forcing it to run on.
With the release of Android Gradle Plugin (AGP) 8.0, the Android ecosystem has enforced a hard floor of JDK 17. If your Flutter project’s Gradle wrapper or AGP version is outdated, the build fails immediately.
Here is the root cause analysis and the definitive, step-by-step upgrade path to resolve this for modern Flutter applications.
The Root Cause: The Dependency Chain
The breakdown occurs due to a violation of the compatibility matrix between three components:
- The Gradle Daemon: The process running the build.
- The Android Gradle Plugin (AGP): The logic that builds the APK/AAB.
- The Java Development Kit (JDK): The environment compiling the code.
The Breaking Change: Android Gradle Plugin 8.0+ removed support for Java 11. It requires the build to run on Java 17. Consequently, AGP 8.0+ requires Gradle 8.0+.
If you attempt to run Gradle 7.5 (common in older Flutter projects) using JDK 17, Gradle 7 fails because it doesn't fully understand class file version 61. Conversely, if you run Gradle 8 using JDK 11, AGP complains that it needs JDK 17.
The Fix: Aligning the Stack
To fix this, we must align the Gradle Wrapper, the AGP version, and the compiler options to target Java 17 (or 21, if using the absolute latest Gradle).
1. Upgrade the Gradle Wrapper
First, update the distribution URL to a version of Gradle compatible with JDK 17+. Gradle 8.2 or higher is recommended for stability with modern AGP.
File: android/gradle/wrapper/gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
# Upgrade to Gradle 8.4 (or latest stable 8.x)
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
2. Update Android Gradle Plugin (AGP) Version
Next, update the root-level build configuration to use an AGP version compatible with Gradle 8.
File: android/build.gradle (Root Project)
Note: Depending on when your Flutter project was created, you may use the legacy buildscript block or the modern plugins DSL. Most existing projects use buildscript.
buildscript {
ext.kotlin_version = '1.9.22' // Ensure Kotlin is also updated
repositories {
google()
mavenCentral()
}
dependencies {
// AGP 8.1.0+ is required for Gradle 8 compatibility
classpath 'com.android.tools.build:gradle:8.2.0'
// Ensure your Kotlin Gradle plugin matches the ext version
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
3. Configure Java 17 in the App Module
Finally, explicitly tell the compiler to generate bytecode compatible with Java 17. If you skip this, you may encounter kapt or compile-time errors regarding source compatibility.
File: android/app/build.gradle
android {
// Namespace is required in AGP 8+ (replace with your actual package name)
namespace "com.example.your_app_name"
compileSdkVersion 34 // Target Android 14
compileOptions {
// STRICTLY REQUIRED: Target Java 17
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
// Ensure Kotlin compiles to JVM 17 bytecode
jvmTarget = '17'
}
defaultConfig {
applicationId "com.example.your_app_name"
minSdkVersion 21 // Flutter default minimum
targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// R8 is enabled by default in AGP 8, standard settings apply
signingConfig signingConfigs.debug
}
}
}
4. Verify the Environment (IDE & Terminal)
Configuration files are useless if the machine ignores them. You must ensure the terminal running flutter build is using the correct JDK.
For macOS/Linux: Check your active JDK:
java -version
If it does not say "17" (or newer), you must adjust your JAVA_HOME.
# Example for ~/.zshrc or ~/.bashrc
export JAVA_HOME="/path/to/your/jdk-17-home"
export PATH=$JAVA_HOME/bin:$PATH
For Android Studio:
- Open
android/folder as a project in Android Studio. - Go to Settings/Preferences > Build, Execution, Deployment > Build Tools > Gradle.
- Set Gradle JDK to jbr-17 (JetBrains Runtime 17) or your installed JDK 17.
Why This Works
This solution resolves the deadlock by synchronizing the toolchain:
- Gradle 8.4 has the internal capability to run on JDK 17+.
- AGP 8.2.0 is designed to communicate with Gradle 8.4 and assumes the JVM environment is Java 17.
jvmTarget = '17'ensures that the Kotlin compiler emits bytecode that utilizes Java 17 features (like Records or Sealed Classes) without crashing the downstream dexer (D8/R8).namespacedeclaration fixes the removal of the package attribute inAndroidManifest.xml, a breaking change introduced in AGP 8.0.
By performing these upgrades simultaneously, you eliminate the "Unsupported class file major version" error because the Gradle Daemon, the Plugin, and the Compiler are finally speaking the same language version.