{"record":{"id":"dd54b5e0439bb747","repo":"quarkusio/quarkus","slug":"address-already-in-use-by","errorCode":null,"errorMessage":"address already in use by: ","messagePattern":"address already in use by: ","errorType":"exception","errorClass":"ChannelException","httpStatus":null,"severity":"error","filePath":"extensions/netty/runtime/src/main/java/io/quarkus/netty/runtime/virtual/VirtualChannelRegistry.java","lineNumber":46,"sourceCode":"    private static final ConcurrentMap<VirtualAddress, Channel> boundChannels = PlatformDependent.newConcurrentHashMap();\n\n    static VirtualAddress register(\n            Channel channel, VirtualAddress oldLocalAddress, SocketAddress localAddress) {\n        if (oldLocalAddress != null) {\n            throw new ChannelException(\"already bound\");\n        }\n        if (!(localAddress instanceof VirtualAddress)) {\n            throw new ChannelException(\"unsupported address type: \" + StringUtil.simpleClassName(localAddress));\n        }\n\n        VirtualAddress addr = (VirtualAddress) localAddress;\n        if (VirtualAddress.ANY.equals(addr)) {\n            addr = new VirtualAddress(channel);\n        }\n\n        Channel boundChannel = boundChannels.putIfAbsent(addr, channel);\n        if (boundChannel != null) {\n            throw new ChannelException(\"address already in use by: \" + boundChannel);\n        }\n        return addr;\n    }\n\n    static Channel get(SocketAddress localAddress) {\n        return boundChannels.get(localAddress);\n    }\n\n    static void unregister(VirtualAddress localAddress) {\n        boundChannels.remove(localAddress);\n    }\n\n    private VirtualChannelRegistry() {\n        // Unused\n    }\n}\n","sourceCodeStart":28,"sourceCodeEnd":63,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/netty/runtime/src/main/java/io/quarkus/netty/runtime/virtual/VirtualChannelRegistry.java#L28-L63","documentation":"When binding a virtual channel, the registry stores the address→channel mapping atomically with putIfAbsent. If another channel is already bound to that VirtualAddress, the bind fails with ChannelException(\"address already in use by: <channel>\") — the virtual equivalent of the OS 'address already in use' error.","triggerScenarios":"Two channels trying to bind the same VirtualAddress concurrently or sequentially without the first being unbound; re-binding a server on an address whose previous channel was never closed/unregistered.","commonSituations":"Dev-mode live reload where the old virtual server channel still holds the address; parallel tests each trying to bind the same in-memory address; leaked channels from earlier failed runs keeping registry entries alive.","solutions":["Close/unbind the existing channel that holds the address before binding again.","Bind with VirtualAddress.ANY (or a unique VirtualAddress) to let the registry assign an address.","Track and reuse the original bound channel instead of creating a new one on restart."],"exampleFix":"// before\nChannel old = VirtualChannelRegistry.get(addr);\n// assume free, but it is not:\nserverChannel.bind(addr); // ChannelException\n// after\nChannel existing = VirtualChannelRegistry.get(addr);\nif (existing != null) { existing.close().syncUninterruptibly(); }\nserverChannel.bind(addr);","handlingStrategy":"try-catch","validationCode":"Channel existing = VirtualChannelRegistry.get(addr);\nif (existing != null && existing.isActive()) {\n    throw new IllegalStateException(\"address \" + addr + \" already bound by \" + existing);\n}","typeGuard":null,"tryCatchPattern":"try {\n    channel.bind(addr).sync();\n} catch (ChannelException e) {\n    if (e.getMessage().startsWith(\"address already in use\")) {\n        Channel holder = VirtualChannelRegistry.get(addr);\n        if (holder != null) holder.close().syncUninterruptibly();\n        channel.bind(addr).sync();\n    } else { throw e; }\n}","preventionTips":["Close old server channels before rebinding the same virtual address","Bind with VirtualAddress.ANY for unique per-channel addresses in tests","Ensure test teardown closes all virtual channels to free registry entries"],"tags":["netty","virtual-channel","bind","address-in-use"],"backgroundTag":"address-already-in-use","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}