quarkusio/quarkus · error · IllegalStateException

Invalid signature char:

Error message

Invalid signature char: 

What it means

AsmUtil.getParameterTypes parses a JVM method descriptor string (e.g. (IJ)Ljava/lang/String;) into Jandex Types. Any character in the argument section that is not a primitive descriptor char (Z B C D F I J S), 'L', or '[' throws IllegalStateException("Invalid signature char: "), meaning the descriptor is malformed or uses a construct the simple parser does not support (e.g. 'V' for void arguments, 'T' type-variable signatures).

Source

Thrown at core/deployment/src/main/java/io/quarkus/deployment/util/AsmUtil.java:426

                    int end = argsSignature.indexOf(';', i);
                    String binaryName = argsSignature.substring(i + 1, end);
                    // arrays take the entire signature
                    if (dimensions > 0) {
                        args.add(Type.create(DotName.createSimple(argsSignature.substring(start, end + 1).replace('/', '.')),
                                Kind.ARRAY));
                        dimensions = 0;
                    } else {
                        // class names take only the binary name
                        args.add(Type.create(DotName.createSimple(binaryName.replace('/', '.')), Kind.CLASS));
                    }
                    i = end; // we will have a ++ to get after the ;
                    start = i + 1;
                    break;
                case '[':
                    dimensions++;
                    break;
                default:
                    throw new IllegalStateException("Invalid signature char: " + c);
            }
        }
        return args.toArray(new Type[0]);
    }

    /**
     * Returns the number of underlying bytecode parameters taken by the given Jandex parameter Type.
     * This will be 2 for doubles and longs, 1 otherwise.
     *
     * @param paramType the Jandex parameter Type
     * @return the number of underlying bytecode parameters required.
     */
    public static int getParameterSize(Type paramType) {
        if (paramType.kind() == Kind.PRIMITIVE) {
            switch (paramType.asPrimitiveType().primitive()) {
                case DOUBLE:
                case LONG:
                    return 2;

View on GitHub (pinned to e1c734241f)

Solutions

  1. Pass only the plain bytecode descriptor (method.descriptor()), not the generic signature — Jandex exposes the descriptor via MethodInfodescriptor()/name 'descriptor'
  2. Strip everything outside the parentheses and ensure only legal descriptor chars are inside
  3. Validate the descriptor with a regex like ^\((\[*[ZBCDFIJS]|\[*L[^;:<>]+;)*\).+$ before calling
  4. If you have a Jandex MethodInfo, prefer method.parameterTypes() over parsing the descriptor manually

Example fix

// before
Type[] params = AsmUtil.getParameterTypes(method.genericSignature());
// after
Type[] params = method.parameterTypes(); // or use method.descriptor()
Defensive patterns

Strategy: validation

Validate before calling

private static final java.util.regex.Pattern DESCRIPTOR =
    java.util.regex.Pattern.compile("^\\((\\[*[ZBCDFIJS]|\\[*L[^.;<>\\[\\]]*;)*\\)\\[*(V|Z|B|C|D|F|I|J|S|L[^.;<>\\[\\]]*;)$");
if (!DESCRIPTOR.matcher(methodDescriptor).matches()) {
    throw new IllegalArgumentException("Not a plain method descriptor: " + methodDescriptor);
}

Type guard

static boolean isPlainMethodDescriptor(String s) {
    return s.startsWith("(") && s.contains(")") && !s.contains("<") && !s.contains("T;");
}

Try / catch

try {
    Type[] params = AsmUtil.getParameterTypes(desc);
} catch (IllegalStateException e) {
    throw new IllegalArgumentException("Malformed method descriptor '" + desc + "'", e);
}

Prevention

When it happens

Trigger: Passing a string that is not a well-formed method descriptor to AsmUtil.getParameterTypes — e.g. including the return type, a generic signature like (TT;)V or (Ljava/util/List<Ljava/lang/String;>;)V, or a truncated/corrupted descriptor.

Common situations: Hand-building descriptors in tests or recorders; passing a generic signature (from ClassInfo.genericSignature) instead of the plain descriptor; reading descriptors from non-class files.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/b1efe6e6bfb53133. Report an issue: GitHub.