quarkusio/quarkus · error · WebSocketServerException

Multiple endpoints [%s, %s] define the same endpoint id: %s

Error message

Multiple endpoints [%s, %s] define the same endpoint id: %s

What it means

Every server endpoint has an id, taken from @WebSocket(endpointId=...) or defaulting to the class name. Ids must be unique because WebSocketConnection.ConnectionOpenOptions/endpoints are looked up by id; a collision fails deployment with WebSocketServerException.

Source

Thrown at extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/WebSocketProcessor.java:372

                path = getPath(webSocketAnnotation.value("path").asString());
                if (beanClass.nestingType() == NestingType.INNER) {
                    // Sub-websocket - merge the path from the enclosing classes
                    path = mergePath(getPathPrefix(index, beanClass.enclosingClass()), path);
                }
                DotName prevPath = serverPathToEndpoint.put(path, beanClass.name());
                if (prevPath != null) {
                    throw new WebSocketServerException(
                            String.format("Multiple endpoints [%s, %s] define the same path: %s", prevPath, beanClass, path));
                }
                AnnotationValue endpointIdValue = webSocketAnnotation.value("endpointId");
                if (endpointIdValue == null) {
                    id = beanClass.name().toString();
                } else {
                    id = endpointIdValue.asString();
                }
                DotName prevId = serverIdToEndpoint.put(id, beanClass.name());
                if (prevId != null) {
                    throw new WebSocketServerException(
                            String.format("Multiple endpoints [%s, %s] define the same endpoint id: %s", prevId, beanClass,
                                    id));
                }
                inboundProcessingMode = webSocketAnnotation.value("inboundProcessingMode");
            } else {
                target = Target.CLIENT;
                path = getPath(webSocketClientAnnotation.value("path").asString());
                DotName prevPath = clientPathToEndpoint.put(path, beanClass.name());
                if (prevPath != null) {
                    throw new WebSocketServerException(
                            String.format("Multiple client endpoints [%s, %s] define the same path: %s", prevPath, beanClass,
                                    path));
                }
                AnnotationValue clientIdValue = webSocketClientAnnotation.value("clientId");
                if (clientIdValue == null) {
                    id = beanClass.name().toString();
                } else {
                    id = clientIdValue.asString();

View on GitHub (pinned to e1c734241f)

Solutions

  1. Change the endpointId value on one of the endpoints
  2. Remove the explicit endpointId so the unique class name is used
  3. Search the codebase for the duplicated endpointId string to find both occurrences

Example fix

// before
@WebSocket(path="/a", endpointId="chat") class A {}
@WebSocket(path="/b", endpointId="chat") class B {}
// after
@WebSocket(path="/b", endpointId="chat-admin") class B {}
Defensive patterns

Strategy: validation

Validate before calling

@Test
void endpointIdsUnique() {
  Set<String> ids = new HashSet<>();
  for (Class<?> c : allEndpoints) {
    WebSocket ws = c.getAnnotation(WebSocket.class);
    String id = ws.endpointId().isEmpty() ? c.getName() : ws.endpointId();
    if (!ids.add(id)) throw new AssertionError("Duplicate endpointId: " + id);
  }
}

Prevention

When it happens

Trigger: Two @WebSocket classes both declaring the same endpointId value, or one explicitly set equal to another class's implicit id (the fully-qualified class name).

Common situations: Copying an endpoint with its endpointId attribute; refactoring class names so a chosen endpointId now collides; generating endpoints where ids are templated incorrectly.

Related errors


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