oracle/graal · error · IOException

The image file "{name}" is not the correct version. Major: {

Error message

The image file "{name}" is not the correct version. Major: {major}. Minor: {minor}

What it means

While reading a jimage header, BasicImageReader checks magic, then major/minor version against ImageHeader.MAJOR_VERSION/MINOR_VERSION. A mismatch means the file is a jimage written by a different (incompatible) JDK image format version; an IOException with the found version numbers is thrown.

Source

Thrown at espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/runtime/jimage/BasicImageReader.java:114

    public static final class NotAnImageFile extends IOException {
        static final long serialVersionUID = -3240111096036918189L;
    }

    public static BasicImageReader open(Path path) throws IOException {
        return new BasicImageReader(path, ByteOrder.nativeOrder());
    }

    private ImageHeader readHeader(IntBuffer buffer) throws IOException {
        ImageHeader result = ImageHeader.readFrom(buffer);

        if (result.getMagic() != ImageHeader.MAGIC) {
            throw new NotAnImageFile();
        }

        if (result.getMajorVersion() != ImageHeader.MAJOR_VERSION ||
                        result.getMinorVersion() != ImageHeader.MINOR_VERSION) {
            throw new IOException("The image file \"" + name + "\" is not " +
                            "the correct version. Major: " + result.getMajorVersion() +
                            ". Minor: " + result.getMinorVersion());
        }

        return result;
    }

    private static ByteBuffer slice(ByteBuffer buffer, int position, int capacity) {
        // Note that this is the only limit and position manipulation of
        // BasicImageReader private ByteBuffers. The synchronize could be avoided
        // by cloning the buffer to make a local copy, but at the cost of creating
        // a new object.
        synchronized (buffer) {
            buffer.limit(position + capacity);
            buffer.position(position);
            return buffer.slice();
        }
    }

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Use a java home whose JDK version is supported by your GraalVM/Espresso release (check release notes for supported JDK versions).
  2. If you deliberately need a different JDK's runtime, upgrade GraalVM to a matching distribution (Espresso tracks specific JDK versions).
  3. Verify you are not pointing at a non-JDK directory that happens to contain a lib/modules file.
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the java home matches a JDK version supported by this GraalVM build
String v = Files.readString(Path.of(javaHome, "release")).lines()
    .filter(l -> l.startsWith("JAVA_VERSION=")).findFirst().orElseThrow();
// compare against the supported version list for your GraalVM release

Try / catch

try {
    reader = new BasicImageReader(path);
} catch (IOException e) {
    if (e.getMessage().contains("not the correct version")) { /* switch java home / upgrade GraalVM */ }
}

Prevention

When it happens

Trigger: Opening a jimage produced by a JDK whose image format differs from the one this Espresso build understands (e.g. newer/older JDK modules file passed via JavaHome).

Common situations: Running Espresso with a --java-home of a much newer or older JDK than the GraalVM build supports; mixing toolchains; custom-built jimage files with different format versions.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/77169cbabb5f5dd3. Report an issue: GitHub.