quarkusio/quarkus · error · IllegalStateException

Method already defined: ${fullyQualifiedMethodName} in ${ful

Error message

Method already defined: ${fullyQualifiedMethodName} in ${fullyQualifiedServiceName}

What it means

While indexing reflection metadata, every method's fully qualified name (package.Service.Method) must be unique. processService throws this IllegalStateException when a method full name was already registered in the descriptorsBySymbol map.

Source

Thrown at extensions/grpc/reflection/src/main/java/io/quarkus/grpc/reflection/service/GrpcServerIndex.java:132

        for (Descriptors.Descriptor type : fd.getMessageTypes()) {
            processType(type, fd, descriptorsBySymbol, descriptorsByExtensionAndNumber);
        }
        for (Descriptors.FieldDescriptor extension : fd.getExtensions()) {
            processExtension(extension, fd, descriptorsByExtensionAndNumber);
        }
    }

    private void processService(Descriptors.ServiceDescriptor service, FileDescriptor fd,
            Map<String, FileDescriptor> descriptorsBySymbol) {
        String fullyQualifiedServiceName = service.getFullName();
        if (descriptorsBySymbol.containsKey(fullyQualifiedServiceName)) {
            throw new IllegalStateException("Service already defined: " + fullyQualifiedServiceName);
        }
        descriptorsBySymbol.put(fullyQualifiedServiceName, fd);
        for (Descriptors.MethodDescriptor method : service.getMethods()) {
            String fullyQualifiedMethodName = method.getFullName();
            if (descriptorsBySymbol.containsKey(fullyQualifiedMethodName)) {
                throw new IllegalStateException(
                        "Method already defined: " + fullyQualifiedMethodName + " in " + fullyQualifiedServiceName);
            }
            descriptorsBySymbol.put(fullyQualifiedMethodName, fd);
        }
    }

    private void processType(Descriptors.Descriptor type, FileDescriptor fd,
            Map<String, FileDescriptor> descriptorsBySymbol,
            Map<String, Map<Integer, FileDescriptor>> descriptorsByExtensionAndNumber) {
        String fullyQualifiedTypeName = type.getFullName();
        if (descriptorsBySymbol.containsKey(fullyQualifiedTypeName)) {
            throw new IllegalStateException("Type already defined: " + fullyQualifiedTypeName);
        }
        descriptorsBySymbol.put(fullyQualifiedTypeName, fd);
        for (Descriptors.FieldDescriptor extension : type.getExtensions()) {
            processExtension(extension, fd, descriptorsByExtensionAndNumber);
        }
        for (Descriptors.Descriptor nestedType : type.getNestedTypes()) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure unique proto packages so method full names cannot collide.
  2. Remove duplicated proto sources/dependencies (mvn dependency:tree, exclude the extra artifact).
  3. Rename the colliding method in the duplicate proto.
  4. Regenerate stubs after fixing (mvn clean) so stale descriptors don't linger.

Example fix

// before
package p; service S { rpc Get (Req) returns (Res); }  // in two files
// after
// second file: package p2; service S { rpc Get (Req) returns (Res); }
Defensive patterns

Strategy: try-catch

Try / catch

try {
    startServer();
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Method already defined:")) {
        // the message names method and service; adjust the colliding proto package
    } else throw e;
}

Prevention

When it happens

Trigger: Two service definitions contain methods resolving to the same fully qualified method name — normally a symptom of a duplicated service/method declaration across proto files processed earlier.

Common situations: Two proto packages generating the same package.Service.Method trio; the same proto compiled into two classpath artifacts; misconfigured proto include paths causing double generation.

Related errors


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