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

  1. Construct and pass a VirtualAddress (e.g. new VirtualAddress(channel) or VirtualAddress.ANY) instead of InetSocketAddress.
  2. Ensure the bootstrap is configured for the virtual transport channel types when using virtual addresses.
  3. 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

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


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