oracle/graal · error · IOException

Unsupported replay file version

Error message

Unsupported replay file version 

What it means

After the MAGIC bytes verify, verifyHeader reads a packed version int and compares it to the codec's VERSION constant. A mismatch throws IOException 'Unsupported replay file version <version>'. The version guards the whole binary layout: any change to tags or encoding bumps VERSION so stale files are rejected deterministically instead of producing random decode errors.

Source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/BinaryReplayCodec.java:1060

            String value = readStringReference(in, state);
            properties.put(key, value);
        }
        return properties;
    }

    private static void verifyHeader(ObjectCopierInputStream in) throws IOException {
        for (byte expected : MAGIC) {
            int actual = in.read();
            if (actual < 0) {
                throw new EOFException();
            }
            if (actual != Byte.toUnsignedInt(expected)) {
                throw new IOException("Invalid replay file header");
            }
        }
        int version = in.readPackedUnsignedInt();
        if (version != VERSION) {
            throw new IOException("Unsupported replay file version " + version);
        }
    }

    private static void writeBooleanFlag(ObjectCopierOutputStream out, boolean value) throws IOException {
        out.write(value ? 1 : 0);
    }

    private static boolean readBooleanFlag(ObjectCopierInputStream in) throws IOException {
        int value = in.read();
        if (value < 0) {
            throw new EOFException();
        }
        return switch (value) {
            case 0 -> false;
            case 1 -> true;
            default -> throw new IOException("Invalid replay boolean flag " + value);
        };
    }

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Re-record the replay file with the same GraalVM build that will replay it
  2. Upgrade or downgrade the replaying JVM so its codec VERSION matches the file
  3. If you must carry old files forward, write a migration tool that decodes with the old version and re-encodes

Example fix

// before
verifyHeader(in); // throws mid-run on version mismatch

// after
// surface the mismatch clearly up front
if (fileVersion != VERSION) {
    throw new IOException("Replay file version " + fileVersion + " does not match codec version " + VERSION + "; re-record with this build");
}
Defensive patterns

Strategy: validation

Validate before calling

static void assertVersionMatch(java.io.InputStream in, int codecVersion) throws IOException {
    // assumes magic already consumed
    int v = new ObjectCopierInputStream(in).readPackedUnsignedInt();
    if (v != codecVersion) throw new IOException("Unsupported replay file version " + v);
}

Try / catch

try {
    codec.readReplay(in);
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Unsupported replay file version")) {
        // re-record on this build or switch to the matching build
    } else throw e;
}

Prevention

When it happens

Trigger: Replaying a file recorded by an older or newer GraalVM build whose codec VERSION differs from the reader's.

Common situations: Upgrading GraalVM between recording a bug and replaying it; sharing replay files across teams on different builds; keeping old replay files in a test corpus after a codec format change.

Related errors


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