quarkusio/quarkus · error · RuntimeException
Should be virtual server channel:
Error message
Should be virtual server channel:
What it means
VirtualClientConnection.connect() looks up a server-side channel registered in VirtualChannelRegistry for the given remote address and requires it to be a VirtualServerChannel. If the bound object is a different Channel implementation, the registry contents are inconsistent with the virtual transport's expectations, so a RuntimeException is thrown naming the offending class.
Source
Thrown at extensions/netty/runtime/src/main/java/io/quarkus/netty/runtime/virtual/VirtualClientConnection.java:120
/**
* Establish a virtual intra-JVM connection
*
* @param remoteAddress
* @param clientAddress
* @return
*/
public static VirtualClientConnection connect(VirtualResponseHandler handler, VirtualAddress remoteAddress,
SocketAddress clientAddress) {
if (clientAddress == null)
clientAddress = remoteAddress;
Channel boundChannel = VirtualChannelRegistry.get(remoteAddress);
if (boundChannel == null) {
throw new RuntimeException("No virtual channel available");
}
if (!(boundChannel instanceof VirtualServerChannel)) {
throw new RuntimeException("Should be virtual server channel: " + boundChannel.getClass().getName());
}
VirtualServerChannel serverChannel = (VirtualServerChannel) boundChannel;
VirtualClientConnection conn = new VirtualClientConnection(clientAddress, handler);
conn.peer = serverChannel.serve(conn);
return conn;
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Ensure the address bound in VirtualChannelRegistry was created via VirtualServerChannel bind/registration, not a client channel
- Inspect the class name in the message to find what actually got registered under that address
- Clear or reset VirtualChannelRegistry between tests so stale client channels are not reused
Example fix
// before VirtualChannelRegistry.register(remoteAddress, someVirtualClientChannel); // after VirtualServerChannel server = ...; // create via virtual server bootstrap server.bind(remoteAddress).sync(); VirtualClientConnection.connect(bootstrap, remoteAddress, clientAddress, handler);
Defensive patterns
Strategy: validation
Validate before calling
Channel boundChannel = VirtualChannelRegistry.get(remoteAddress);
if (!(boundChannel instanceof VirtualServerChannel)) {
throw new IllegalStateException("Address not bound to a VirtualServerChannel: " + remoteAddress);
} Type guard
static boolean isVirtualServerBound(SocketAddress addr) {
Channel ch = VirtualChannelRegistry.get(addr);
return ch instanceof VirtualServerChannel;
} Try / catch
try {
VirtualClientConnection conn = VirtualClientConnection.connect(bootstrap, remoteAddress, clientAddress, handler);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("Should be virtual server channel")) { /* re-register correct server channel */ }
} Prevention
- Only register VirtualServerChannel instances in VirtualChannelRegistry
- Reset the registry between tests
- Log the registered channel type when binding
When it happens
Trigger: Calling VirtualClientConnection.connect(...) with a remoteAddress that maps in VirtualChannelRegistry to a Channel that is not a VirtualServerChannel (e.g. a VirtualClientChannel or a real Netty channel registered under the same address).
Common situations: Tests or custom code registering the wrong channel type in VirtualChannelRegistry; reusing an address that was bound by a client connection rather than a VirtualServerChannel.bind(); stale registry entries across test cases.
Related errors
- Failed to create compiler
- Tests already in progress
- className parameter is required
- IOException(e)
- Could not find Jetty NPN/ALPN or Conscrypt as installed JDK
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/c166e892bf2d5fa9.
Report an issue: GitHub.