quarkusio/quarkus · error · RuntimeException

Wrong class path version

Error message

Wrong class path version

What it means

SerializedApplication.read deserializes the fast-jar application manifest that Quarkus generated at build time. After checking the magic number, it verifies the serialized class path VERSION constant; if the stream's version differs from the reader's expected VERSION, it throws 'Wrong class path version'. This protects against running an app root produced by an incompatible Quarkus build.

Source

Thrown at independent-projects/bootstrap/runner/src/main/java/io/quarkus/bootstrap/runner/SerializedApplication.java:138

            data.writeShort(fullyIndexedResourcesToCPJarIndex.size());
            for (Map.Entry<String, List<Integer>> entry : fullyIndexedResourcesToCPJarIndex.entrySet()) {
                data.writeUTF(entry.getKey());
                data.writeShort(entry.getValue().size());
                for (Integer index : entry.getValue()) {
                    data.writeShort(index);
                }
            }
            data.flush();
        }
    }

    public static SerializedApplication read(InputStream inputStream, Path appRoot) throws IOException {
        try (DataInputStream in = new DataInputStream(inputStream)) {
            if (in.readInt() != MAGIC) {
                throw new RuntimeException("Wrong magic number");
            }
            if (in.readInt() != VERSION) {
                throw new RuntimeException("Wrong class path version");
            }
            String mainClass = in.readUTF();
            ResourceDirectoryTracker resourceDirectoryTracker = new ResourceDirectoryTracker();
            int numPaths = in.readUnsignedShort();
            ClassLoadingResource[] allClassLoadingResources = new ClassLoadingResource[numPaths];
            ClassLoadingResource generatedBytecodeClassLoadingResource = null;
            Set<String> generatedBytecode = Set.of();
            ClassLoadingResource transformedBytecodeClassLoadingResource = null;
            Set<String> transformedBytecode = Set.of();
            for (int pathCount = 0; pathCount < numPaths; pathCount++) {
                String path = in.readUTF();
                boolean hasManifest = in.readBoolean();
                ManifestInfo info = null;
                if (hasManifest) {
                    info = new ManifestInfo(readNullableString(in), readNullableString(in), readNullableString(in),
                            readNullableString(in), readNullableString(in), readNullableString(in));
                }
                JarResource resource = new JarResource(info, appRoot.resolve(path));

View on GitHub (pinned to e1c734241f)

Solutions

  1. Rebuild the whole application with the same Quarkus version used by the runner (mvn clean package or gradle clean build)
  2. Ensure the quarkus-run.jar / bootstrap runner version matches the version that produced the app artifacts — do not mix runner jars across Quarkus releases
  3. Delete stale target/ or build/ directories and regenerate the fast-jar output
  4. If reading programmatically, use a SerializedApplication reader from the same Quarkus version that built the application

Example fix

// before: mixing runner and app from different versions
java -jar old-quarkus-run/quarkus-run.jar -jarg new-app/quarkus-application.dat
// after: regenerate both from one build
./mvnw clean package && java -jar target/quarkus-app/quarkus-run.jar
Defensive patterns

Strategy: try-catch

Validate before calling

// Java: pre-check the serialized app version before reading fully
try (DataInputStream in = new DataInputStream(Files.newInputStream(appFile))) {
    int magic = in.readInt();
    int version = in.readInt();
    if (magic != MAGIC || version != EXPECTED_VERSION) {
        throw new IllegalStateException("App built with incompatible Quarkus version (version=" + version + "); rebuild required");
    }
}

Type guard

static boolean isCompatibleVersion(int version) { return version == VERSION; }

Try / catch

try {
    SerializedApplication app = SerializedApplication.read(in, appRoot);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().contains("Wrong class path version")) {
        throw new IllegalStateException("Runner and application Quarkus versions differ; run a clean rebuild", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling SerializedApplication.read(InputStream, Path) on an io.quarkus.app-files (serialized application) file whose embedded int version does not equal the VERSION constant compiled into the reader — typically when the app-cd/binaries were built by a different Quarkus version than the one loading them.

Common situations: Mixed-version deployments: rebuilding only part of an application with a newer Quarkus, copying an old quarkus-run.jar against a new application artifact (or vice versa), or stale build output in target/ after a Quarkus upgrade.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/02aac8e107d79537. Report an issue: GitHub.