oracle/graal · error · IllegalArgumentException
Unknown tag %d
Error message
Unknown tag %d
What it means
BinaryInput.readValue dispatches on a one-byte type tag written by BinaryOutput.writeValue. Tags cover boxed primitives (BOOLEAN, BYTE, CHAR, INT, LONG, FLOAT, DOUBLE) and STRING; anything else throws IllegalArgumentException(String.format("Unknown tag %d", tag)). An unknown tag means the stream is misaligned or produced by an incompatible protocol version.
Source
Thrown at compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryInput.java:359
return readBoolean();
case BYTE:
return readByte();
case SHORT:
return readShort();
case CHAR:
return readChar();
case INT:
return readInt();
case LONG:
return readLong();
case FLOAT:
return readFloat();
case DOUBLE:
return readDouble();
case STRING:
return readUTF();
default:
throw new IllegalArgumentException(String.format("Unknown tag %d", tag));
}
}
/**
* Reads {@code len} bytes into a boolean array starting at offset {@code off}.
*
* @throws IndexOutOfBoundsException if there are not enough bytes to read
*/
public final void read(boolean[] b, int off, int len) {
ensureBufferSize(len);
read(tempEncodingByteBuffer, 0, len);
int limit = off + len;
for (int i = off, j = 0; i < limit; i++) {
b[i] = tempEncodingByteBuffer[j++] != 0;
}
}
/**View on GitHub (pinned to a66e9ccd1d)
Solutions
- Ensure the writing and reading sides come from the same GraalVM/libgraal build.
- Audit the sequence of read calls to confirm each consumes exactly the bytes its write counterpart produced.
- Do not interleave manual buffer reads with readValue on the same stream.
- If a tag value >= some new constant appears, upgrade the reader side to the version that defines it.
Defensive patterns
Strategy: validation
Validate before calling
// Before readValue, sanity-check the tag byte
int tag = in.readByte(); // or peek if available
if (tag != BOOLEAN && tag != BYTE && tag != CHAR && tag != INT && tag != LONG && tag != FLOAT && tag != DOUBLE && tag != STRING) {
throw new IllegalArgumentException("stream misaligned; unexpected tag " + tag);
} Try / catch
try {
Object v = in.readValue();
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Unknown tag")) {
// abort the record: version mismatch or desync; renegotiate format version
}
} Prevention
- Pin writer and reader to the same GraalVM build
- Never interleave manual reads with readValue
- Version-stamp the stream header to detect protocol drift early
When it happens
Trigger: Calling readValue when the input position sits on a byte that is not a valid type tag — e.g. after a previous read consumed too few/many bytes, or when the writer used a newer BinaryOutput with extra tags the reader's BinaryInput does not know.
Common situations: GraalVM version mismatch between the process embedding libgraal and the libgraal image; a manual read of the raw stream; a corrupted native buffer.
Related errors
- Partial character at end
- malformed input: partial character at end
- Len must be non negative but was %d
- String too long to encode, %s bytes
- Unsupported type %s
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/48293b44cf4048e5.
Report an issue: GitHub.