oracle/graal · error · ParserException.ClassFormatError
Invalid type descriptor {}
Error message
Invalid type descriptor {} What it means
Defensive tail of skipValidTypeDescriptor: after the early return for non-'['/non-'L' characters and fully handling the 'L' and '[' cases, the final throw 'Invalid type descriptor <rest>' is only reachable through a switch mismatch. In practice it fires if the method is entered with a character value that is neither a valid single-char descriptor, 'L', nor '[' — e.g. an unexpected control or non-ASCII byte in the descriptor.
Source
Thrown at espresso-shared/src/com.oracle.truffle.espresso.classfile/src/com/oracle/truffle/espresso/classfile/descriptors/TypeSymbols.java:244
if (endIndex > beginIndex + 1 && endIndex < descriptor.length() && descriptor.byteAt(endIndex) == ';') {
return endIndex + 1;
}
throw new ParserException.ClassFormatError("Invalid Java name " + descriptor.subSequence(beginIndex));
}
case '[': {
// compute the number of dimensions
int index = beginIndex;
while (index < descriptor.length() && descriptor.byteAt(index) == '[') {
index++;
}
final int dimensions = index - beginIndex;
if (dimensions > 255) {
throw new ParserException.ClassFormatError("Array with more than 255 dimensions " + descriptor.subSequence(beginIndex));
}
return skipValidTypeDescriptor(descriptor, index, slashes);
}
}
throw new ParserException.ClassFormatError("Invalid type descriptor " + descriptor.subSequence(beginIndex));
}
/**
* Gets the type descriptor for the specified component type descriptor with the specified
* number of dimensions. For example if the number of dimensions is 1, then this method will
* return a descriptor for an array of the component type; if the number of dimensions is 2, it
* will return a descriptor for an array of an array of the component type, etc.
*
* @param type the type descriptor for the component type of the array
* @param dimensions the number of array dimensions
* @return the canonical type descriptor for the specified component type and dimensions
*/
public Symbol<Type> arrayOf(Symbol<Type> type, int dimensions) {
assert dimensions > 0;
if (TypeSymbols.getArrayDimensions(type) + dimensions > 255) {
throw new ParserException.ClassFormatError("Array type with more than 255 dimensions");
}
// Prepend #dimensions '[' to type descriptor.View on GitHub (pinned to a66e9ccd1d)
Solutions
- Sanitize/validate descriptor bytes (printable ASCII, known grammar) before parsing
- If hit while parsing a real class file, report the class/method context — the descriptor itself is corrupt
- Use a strict descriptor validator (regex or full grammar parser) upstream
Example fix
// before: pass raw bytes straight through
Symbol<Type> t = typeSymbols.parse(rawSymbol, 0, true);
// after: validate first
if (!desc.matches("(\[)*(V|Z|C|F|D|B|S|I|J|L[^;.\[]+;)")) throw new ClassFormatException("bad descriptor: " + desc);
Symbol<Type> t = typeSymbols.parse(rawSymbol, 0, true); Defensive patterns
Strategy: try-catch
Validate before calling
if (!desc.matches("(\[)*(V|Z|C|F|D|B|S|I|J|L[^;.\[]+;)")) throw new IllegalArgumentException("Descriptor failed grammar check: " + desc); Try / catch
catch (ParserException.ClassFormatError e) { treat the whole class file as corrupt; skip/quarantine it and report the source artifact } Prevention
- Run a full grammar/regex validation on descriptors from untrusted or fuzzed input
- Sanitize non-ASCII bytes before parsing class-file strings
When it happens
Trigger: Theoretically unreachable for ASCII input because non-'L'/'[' returns early; reachable only via unusual chars that slip past earlier validation or future enum/switch changes. Treat hits as a descriptor containing an unexpected byte (e.g. raw byte > 127 cast to char).
Common situations: Malformed or fuzzed class files with non-ASCII bytes in descriptors; byte-to-char casts producing unexpected values; changes to the descriptor grammar in newer JVM versions.
Related errors
- unknown primitive or void type character:
- invalid descriptor: {}
- invalid type descriptor: {}
- Invalid Java name {}
- Array with more than 255 dimensions {}
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/68bac70123b52014.
Report an issue: GitHub.