quarkusio/quarkus · error · IllegalStateException

Extension name ${extensionName} and number ${extensionNumber

Error message

Extension name ${extensionName} and number ${extensionNumber} are already defined

What it means

When indexing proto extensions for reflection, each extension is keyed by (extension full name, extension number). processExtension throws this IllegalStateException if that name/number pair was already defined, i.e. two descriptors declare the same extension with the same number.

Source

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

            processType(nestedType, fd, descriptorsBySymbol, descriptorsByExtensionAndNumber);
        }
    }

    private void processExtension(Descriptors.FieldDescriptor extension, FileDescriptor fd,
            Map<String, Map<Integer, FileDescriptor>> descriptorsByExtensionAndNumber) {
        String extensionName = extension.getContainingType().getFullName();
        int extensionNumber = extension.getNumber();

        descriptorsByExtensionAndNumber.computeIfAbsent(extensionName,
                new Function<String, Map<Integer, FileDescriptor>>() {
                    @Override
                    public Map<Integer, FileDescriptor> apply(String s) {
                        return new HashMap<>();
                    }
                });

        if (descriptorsByExtensionAndNumber.get(extensionName).containsKey(extensionNumber)) {
            throw new IllegalStateException(
                    "Extension name " + extensionName + " and number " + extensionNumber + " are already defined");
        }
        descriptorsByExtensionAndNumber.get(extensionName).put(extensionNumber, fd);
    }

}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Coordinate extension numbers: give each team/module a distinct extension number range in the shared base proto.
  2. Rename one of the colliding extensions (extension full names must be unique anyway).
  3. Remove duplicated protos from the classpath via dependency exclusions.
  4. Regenerate stubs with a clean build after resolving the collision.

Example fix

// before: both files
extend Base { optional string meta = 100; }
// after: fileB
extend Base { optional string meta_b = 101; }
Defensive patterns

Strategy: validation

Validate before calling

// lint: allocate unique extension numbers per team/module
Map<Integer,String> numbers = new HashMap<>();
for (ExtensionDef e : allExtensions)
  if (numbers.put(e.getNumber(), e.getName()) != null)
    throw new IllegalStateException("Duplicate extension number " + e.getNumber());

Try / catch

try {
    startServer();
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Extension name")) {
        // renumber/rename the colliding extension reported in the message
    } else throw e;
}

Prevention

When it happens

Trigger: Two proto files extend the same message with an extension of the same name and field number; duplicated protos on the classpath re-declaring the same extensions.

Common situations: Two teams declaring extensions for a shared base message using identical names/numbers; duplicated dependency protos containing extension declarations.

Related errors


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