{"record":{"id":"6ac1f4ff3d2ec22f","repo":"quarkusio/quarkus","slug":"service-already-defined-fullyqualifiedservicena","errorCode":null,"errorMessage":"Service already defined: ${fullyQualifiedServiceName}","messagePattern":"Service already defined: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/grpc/reflection/src/main/java/io/quarkus/grpc/reflection/service/GrpcServerIndex.java","lineNumber":126,"sourceCode":"            throw new IllegalStateException(\"File name already used: \" + name);\n        }\n        descriptorsByName.put(name, fd);\n        for (Descriptors.ServiceDescriptor service : fd.getServices()) {\n            processService(service, fd, descriptorsBySymbol);\n        }\n        for (Descriptors.Descriptor type : fd.getMessageTypes()) {\n            processType(type, fd, descriptorsBySymbol, descriptorsByExtensionAndNumber);\n        }\n        for (Descriptors.FieldDescriptor extension : fd.getExtensions()) {\n            processExtension(extension, fd, descriptorsByExtensionAndNumber);\n        }\n    }\n\n    private void processService(Descriptors.ServiceDescriptor service, FileDescriptor fd,\n            Map<String, FileDescriptor> descriptorsBySymbol) {\n        String fullyQualifiedServiceName = service.getFullName();\n        if (descriptorsBySymbol.containsKey(fullyQualifiedServiceName)) {\n            throw new IllegalStateException(\"Service already defined: \" + fullyQualifiedServiceName);\n        }\n        descriptorsBySymbol.put(fullyQualifiedServiceName, fd);\n        for (Descriptors.MethodDescriptor method : service.getMethods()) {\n            String fullyQualifiedMethodName = method.getFullName();\n            if (descriptorsBySymbol.containsKey(fullyQualifiedMethodName)) {\n                throw new IllegalStateException(\n                        \"Method already defined: \" + fullyQualifiedMethodName + \" in \" + fullyQualifiedServiceName);\n            }\n            descriptorsBySymbol.put(fullyQualifiedMethodName, fd);\n        }\n    }\n\n    private void processType(Descriptors.Descriptor type, FileDescriptor fd,\n            Map<String, FileDescriptor> descriptorsBySymbol,\n            Map<String, Map<Integer, FileDescriptor>> descriptorsByExtensionAndNumber) {\n        String fullyQualifiedTypeName = type.getFullName();\n        if (descriptorsBySymbol.containsKey(fullyQualifiedTypeName)) {\n            throw new IllegalStateException(\"Type already defined: \" + fullyQualifiedTypeName);","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/grpc/reflection/src/main/java/io/quarkus/grpc/reflection/service/GrpcServerIndex.java#L108-L144","documentation":"During reflection index building, every service's fully qualified name (package.Service) must be unique across all FileDescriptors. processService throws this IllegalStateException if the symbol map already contains that fully qualified service name.","triggerScenarios":"Two different proto files declare services with the same package+name; a service name collides with an already-recorded symbol from another descriptor processed earlier by processFileDescriptor.","commonSituations":"Copy-pasting a proto into another file without changing the package; importing a third-party proto that redeclares a service with the same full name; code-generating the same proto twice under different file names.","solutions":["Make service full names unique by adjusting the proto 'package' declaration or the service name in the duplicate file.","Delete the duplicated proto copy from your sources or dependencies.","If generated twice by the build, fix duplicate proto source directories in the build config so each proto compiles once.","Verify with a listing of descriptor names before server startup (add a breakpoint/logging in GrpcServerIndex during debugging)."],"exampleFix":"// before: fileA.proto and fileB.proto both contain\npackage my.app;\nservice Greeter {...}\n// after: fileB.proto\npackage my.app.v2;\nservice Greeter {...}","handlingStrategy":"validation","validationCode":"// proto lint: collect all service full names and assert uniqueness\nSet<String> seen = new HashSet<>();\nfor (ProtoFile f : allProtos) {\n  for (ServiceDef s : f.getServices()) {\n    if (!seen.add(f.getPackage() + \".\" + s.getName()))\n      throw new IllegalStateException(\"Duplicate service full name\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n    startServer();\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"Service already defined:\")) {\n        // fix the proto package/name collision reported in the message\n    } else throw e;\n}","preventionTips":["Give each proto file a distinct package","Lint protos for duplicate fully-qualified service names in CI","Don't copy protos between files without renaming the package","Compile each proto exactly once (check source dir config)"],"tags":["grpc","reflection","protobuf","duplicate-symbol"],"backgroundTag":"duplicate-proto-symbol","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}