oracle/graal · error · IOException

Unknown replay marker kind

Error message

Unknown replay marker kind

What it means

Thrown when decoding a RESULT_MARKER_TAG payload: the nested packed int (the marker kind) is not one of RESULT_NO_RESULT, RESULT_NULL, or RESULT_EXCEPTION. The codec therefore cannot map the kind to a SpecialResultMarker and throws IOException 'Unknown replay marker kind'. It almost always indicates stream corruption or a format-version mismatch rather than a runtime condition.

Source

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

                for (int i = 0; i < length; i++) {
                    list.add(readValue(in, state));
                }
                yield list;
            }
            case BYTE_ARRAY_TAG -> in.readByteArrayValue();
            case DOUBLE_ARRAY_TAG -> {
                double[] doubles = new double[in.readPackedUnsignedInt()];
                for (int i = 0; i < doubles.length; i++) {
                    doubles[i] = in.readDoublePrimitive();
                }
                yield doubles;
            }
            case RESULT_MARKER_TAG -> switch (in.readPackedUnsignedInt()) {
                case RESULT_NO_RESULT -> SpecialResultMarker.NO_RESULT_MARKER;
                case RESULT_NULL -> SpecialResultMarker.NULL_RESULT_MARKER;
                case RESULT_EXCEPTION ->
                    new SpecialResultMarker.ExceptionThrownMarker((Throwable) readValue(in, state));
                default -> throw new IOException("Unknown replay marker kind");
            };
            case STACK_TRACE_ELEMENT_TAG ->
                new StackTraceElement(readStringReference(in, state), readStringReference(in, state),
                                readStringReference(in, state), requireNonNullString(readStringReference(in, state), "stack trace holder"),
                                requireNonNullString(readStringReference(in, state), "stack trace method"), readStringReference(in, state), in.readPackedSignedInt());
            case REGISTER_TAG -> findRegister(state.registerArchitecture(), in.readPackedUnsignedInt());
            case FIELD_TAG -> {
                Class<?> holder = ReplayTypeSupport.classCast(ReplayTypeSupport.decodeClass(requireNonNullString(readStringReference(in, state), "field holder")));
                String name = requireNonNullString(readStringReference(in, state), "field name");
                try {
                    if (holder == String.class) {
                        if ("coder".equals(name)) {
                            yield String.class.getDeclaredField("coder");
                        } else if ("value".equals(name)) {
                            yield String.class.getDeclaredField("value");
                        }
                    }
                    yield holder.getDeclaredField(name);

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Regenerate the replay file with the exact GraalVM build used for replay
  2. Confirm the replay file version header matches the reader's VERSION (see verifyHeader) before decoding
  3. If writing a custom extension of the marker kinds, add the corresponding read case for the new kind

Example fix

// before
case RESULT_MARKER_TAG -> switch (in.readPackedUnsignedInt()) {
    ...
    default -> throw new IOException("Unknown replay marker kind");
};

// after
// when the writer knows a kind the reader lacks, bump VERSION so old readers fail fast at verifyHeader
Defensive patterns

Strategy: validation

Validate before calling

// validate the version header before decoding any payload
static void checkVersion(java.io.DataInput in, int expectedVersion) throws IOException {
    int v = in.readInt();
    if (v != expectedVersion) throw new IOException("Unsupported replay file version " + v);
}

Try / catch

try {
    result = codec.readReplay(in);
} catch (IOException e) {
    if ("Unknown replay marker kind".equals(e.getMessage())) {
        // reject the file: writer/reader format mismatch
    } else throw e;
}

Prevention

When it happens

Trigger: Decoding a replay file whose RESULT_MARKER_KIND constants differ from the reader's (newer writer added a kind); bit-level corruption or truncation causing the packed-int read to land on the wrong offset.

Common situations: Replaying files written by a different (usually newer) GraalVM version that extended the marker kinds; hand-editing or partially copying binary replay files.

Related errors


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