oracle/graal · error · IOException

Unknown enum constant for

Error message

Unknown enum constant  for 

What it means

Thrown during replay decoding when an enum value is read: the codec decodes the enum class and constant name from the stream, then linearly searches getEnumConstants() for a matching name. If the enum in the replaying JVM has no constant with the recorded name, it fails with IOException 'Unknown enum constant <name> for <class>'. This is the standard failure mode for record/replay across JVMs whose enum definitions differ.

Source

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

            case STRING_TAG -> readStringReference(in, state);
            case SPECIAL_SINGLETON_TAG -> readSpecialSingleton(in.readPackedUnsignedInt());
            case REGISTERED_SINGLETON_TAG -> state.singletonProxy(in.readPackedUnsignedInt());
            case REGISTERED_INSTANCE_TAG -> state.instanceProxy(in.readPackedUnsignedInt(), in.readPackedUnsignedInt());
            case CLASS_TAG -> ReplayTypeSupport.decodeClass(requireNonNullString(readStringReference(in, state), "class name"));
            case ENUM_TAG -> {
                var enumClass = (Class<? extends Enum<?>>) (Class<?>) ReplayTypeSupport.classCast(
                                ReplayTypeSupport.decodeClass(requireNonNullString(readStringReference(in, state), "enum class")));
                String constantName = requireNonNullString(readStringReference(in, state), "enum constant");
                Enum<?>[] constants = enumClass.getEnumConstants();
                Enum<?> match = null;
                for (Enum<?> constant : constants) {
                    if (constant.name().equals(constantName)) {
                        match = constant;
                        break;
                    }
                }
                if (match == null) {
                    throw new IOException("Unknown enum constant " + constantName + " for " + enumClass.getName());
                }
                yield match;
            }
            case OBJECT_ARRAY_TAG -> {
                Class<?> component = ReplayTypeSupport.classCast(readValue(in, state));
                int length = in.readPackedUnsignedInt();
                Object[] array = (Object[]) Array.newInstance(component, length);
                for (int i = 0; i < length; i++) {
                    array[i] = readValue(in, state);
                }
                yield array;
            }
            case LIST_TAG -> {
                int length = in.readPackedUnsignedInt();
                ArrayList<Object> list = new ArrayList<>(length);
                for (int i = 0; i < length; i++) {
                    list.add(readValue(in, state));
                }

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Re-record the replay file with the same GraalVM/compiler build used for replay
  2. Verify the enum constant still exists in the replaying build (grep the enum source) and update to a build where it does
  3. If the stream may be corrupt, re-generate or re-transfer the replay file and retry

Example fix

// before
Enum<?> e = (Enum<?>) readValue(in, state); // IOException: Unknown enum constant FOO for Bar

// after
// pre-check before decoding if you control the format knowledge
Class<? extends Enum<?>> ec = loadEnumClass();
boolean present = Arrays.stream(ec.getEnumConstants()).anyMatch(c -> c.name().equals(expectedName));
if (!present) throw new IOException("Enum constant missing, re-record replay file");
Defensive patterns

Strategy: try-catch

Validate before calling

<E extends Enum<E>> boolean hasConstant(Class<E> ec, String name) {
    for (E c : ec.getEnumConstants()) if (c.name().equals(name)) return true;
    return false;
}

Try / catch

try {
    result = codec.readReplay(in);
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Unknown enum constant")) {
        // enum skew between record and replay builds: re-record on this build
    } else throw e;
}

Prevention

When it happens

Trigger: Replaying a file recorded on a GraalVM build where the enum had a constant that was renamed or removed in the replaying build; replaying a truncated or corrupted stream where the constant-name string reference resolves incorrectly.

Common situations: Version skew between the recording and replaying GraalVM/compiler builds; replaying files produced by a development branch with extra enum constants; classpath differences that load a different enum version.

Related errors


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