quarkusio/quarkus · error · WebSocketServerException
Multiple endpoints [%s, %s] define the same path: %s
Error message
Multiple endpoints [%s, %s] define the same path: %s
What it means
Quarkus websockets-next maps server endpoint paths to endpoint classes in a build-time registry; two @WebSocket endpoints resolving to the same path (after prefix merging for nested classes) make routing ambiguous, so WebSocketServerException is thrown.
Source
Thrown at extensions/websockets-next/deployment/src/main/java/io/quarkus/websockets/next/deployment/WebSocketProcessor.java:361
} else if (webSocketAnnotation != null && webSocketClientAnnotation != null) {
throw new WebSocketException(
"Endpoint class may not be annotated with both @WebSocket and @WebSocketClient: " + beanClass);
}
String path;
String id;
AnnotationValue inboundProcessingMode;
Target target;
if (webSocketAnnotation != null) {
target = Target.SERVER;
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());View on GitHub (pinned to e1c734241f)
Solutions
- Change one endpoint's @WebSocket path so paths are unique
- Adjust the path prefix of the enclosing class for nested endpoints
- Use distinct path variables/segments to differentiate the endpoints
Example fix
// before
@WebSocket(path = "/ws/echo") class A {}
@WebSocket(path = "/ws/echo") class B {}
// after
@WebSocket(path = "/ws/echo") class A {}
@WebSocket(path = "/ws/echo2") class B {} Defensive patterns
Strategy: validation
Validate before calling
// Unit test guarding path uniqueness across endpoints
@Test
void serverPathsUnique() {
var paths = new HashSet<String>();
for (Class<?> c : List.of(EchoSocket.class, ChatSocket.class)) {
String p = c.getAnnotation(WebSocket.class).path();
if (!paths.add(p)) throw new AssertionError("Duplicate server path: " + p);
}
} Prevention
- Keep an inventory of endpoint paths; add a test asserting uniqueness
- Remember nested endpoints inherit the enclosing class's path prefix
- Use distinct prefixes per feature module
When it happens
Trigger: Two @WebSocket classes with identical path values, or a nested (inner) endpoint whose merged path with its enclosing class prefix collides with another endpoint's path.
Common situations: Copy-pasting an endpoint and forgetting to change the path; two nested websockets that merge to the same prefix + path; dynamic path expressions evaluating to the same literal.
Related errors
- Multiple client endpoints [%s, %s] define the same path: %s
- This method is not supported using this builder. Use #routeF
- Cannot display <routeFunction> on not found page as no expli
- 'RouteBuildItem$Builder.routeFunction' was not set. Ensure t
- Cannot discover value of <routeConfigKey> as no explicit pat
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/6dcbdfce6db88088.
Report an issue: GitHub.