quarkusio/quarkus · error · ChannelException
unsupported address type:
Error message
unsupported address type:
What it means
VirtualChannelRegistry.register only accepts local addresses that are instances of VirtualAddress. Passing any other SocketAddress implementation (e.g. InetSocketAddress, DomainSocketAddress) to the virtual transport's bind path throws ChannelException naming the offending class.
Source
Thrown at extensions/netty/runtime/src/main/java/io/quarkus/netty/runtime/virtual/VirtualChannelRegistry.java:36
import java.net.SocketAddress;
import java.util.concurrent.ConcurrentMap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelException;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.StringUtil;
final class VirtualChannelRegistry {
private static final ConcurrentMap<VirtualAddress, Channel> boundChannels = PlatformDependent.newConcurrentHashMap();
static VirtualAddress register(
Channel channel, VirtualAddress oldLocalAddress, SocketAddress localAddress) {
if (oldLocalAddress != null) {
throw new ChannelException("already bound");
}
if (!(localAddress instanceof VirtualAddress)) {
throw new ChannelException("unsupported address type: " + StringUtil.simpleClassName(localAddress));
}
VirtualAddress addr = (VirtualAddress) localAddress;
if (VirtualAddress.ANY.equals(addr)) {
addr = new VirtualAddress(channel);
}
Channel boundChannel = boundChannels.putIfAbsent(addr, channel);
if (boundChannel != null) {
throw new ChannelException("address already in use by: " + boundChannel);
}
return addr;
}
static Channel get(SocketAddress localAddress) {
return boundChannels.get(localAddress);
}
View on GitHub (pinned to e1c734241f)
Solutions
- Construct and pass a VirtualAddress (e.g. new VirtualAddress(channel) or VirtualAddress.ANY) instead of InetSocketAddress.
- Ensure the bootstrap is configured for the virtual transport channel types when using virtual addresses.
- Refactor address creation behind an abstraction so the correct address type is produced per transport.
Example fix
// before
channel.bind(new InetSocketAddress("localhost", 8080)); // virtual transport: fails
// after
channel.bind(VirtualAddress.ANY); // or new VirtualAddress(channel) Defensive patterns
Strategy: validation
Validate before calling
if (!(socketAddress instanceof VirtualAddress)) {
throw new IllegalArgumentException("virtual transport requires VirtualAddress, got "
+ socketAddress.getClass().getName());
} Type guard
static boolean isVirtualAddress(SocketAddress addr) {
return addr instanceof VirtualAddress;
} Try / catch
try {
channel.bind(localAddress).sync();
} catch (ChannelException e) {
if (e.getMessage().startsWith("unsupported address type")) {
channel.bind(toVirtualAddress(localAddress)).sync();
} else { throw e; }
} Prevention
- Only pass VirtualAddress instances to the virtual transport bind
- Keep address construction next to transport selection
- Add unit tests asserting the address type used per transport
When it happens
Trigger: Binding a virtual-transport channel with a plain SocketAddress that is not a VirtualAddress; mixing regular Netty bootstraps with the virtual channel registry; passing a remote or resolved address object from another transport.
Common situations: Code shared between real-socket and virtual (in-memory) transports where the address type differs per environment; tests that build InetSocketAddress but run against the virtual transport; wrong channel type instantiation (VirtualChannel vs NioServerSocketChannel).
Related errors
- already bound
- address already in use by:
- No virtual channel available
- 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/5f835dbadabb4fc7.
Report an issue: GitHub.