quarkusio/quarkus · critical · RuntimeException
failed to bind virtual http
Error message
failed to bind virtual http
What it means
Quarkus failed to start the internal virtual HTTP bootstrap server used by the Vert.x HTTP extension (e.g. dev-mode virtual hosting / management routing). The Netty bootstrap bind() to the VIRTUAL_HTTP socket threw, most often because the port is already in use or the network interface does not exist, and the wrapping RuntimeException hides the original cause (it is not passed as cause).
Source
Thrown at extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/VertxHttpRecorder.java:1732
ch.pipeline().addLast("handler", handler);
}
private static HttpServerOptions createVirtualHttpServerOptions() {
var result = new HttpServerOptions();
Optional<MemorySize> maybeMaxHeadersSize = ConfigProvider.getConfig()
.getOptionalValue("quarkus.http.limits.max-header-size", MemorySize.class);
if (maybeMaxHeadersSize.isPresent()) {
result.setMaxHeaderSize(maybeMaxHeadersSize.get().asIntValue());
}
return result;
}
});
// Start the server.
try {
virtualBootstrapChannel = virtualBootstrap.bind(VIRTUAL_HTTP).sync();
} catch (InterruptedException e) {
throw new RuntimeException("failed to bind virtual http");
}
}
public static Handler<HttpServerRequest> getRootHandler() {
return ACTUAL_ROOT;
}
/**
* used in the live reload handler to make sure the application has not been changed by another source (e.g. reactive
* messaging)
*/
public static Object getCurrentApplicationState() {
return rootHandler;
}
private static boolean isGrpc(RoutingContext rc) {
HttpServerRequest request = rc.request();View on GitHub (pinned to e1c734241f)
Solutions
- Find and kill the process holding the virtual HTTP port (lsof -i :<port> / netstat -ano), often a leftover Quarkus dev process.
- Check quarkus.http.port / quarkus.management.port and quarkus.http.host in application.properties for conflicts or invalid interfaces.
- Set the port to 0 (random) in dev mode to dodge conflicts.
- Re-run the build with more logging to surface the suppressed cause, since this RuntimeException does not chain the original exception.
- Restart the machine/container if a zombie process cannot be found.
Example fix
// before (application.properties) quarkus.http.port=8080 // after quarkus.http.port=0 # let the OS pick a free port in dev mode
Defensive patterns
Strategy: validation
Validate before calling
int port = Integer.parseInt(config.httpPort());
try (ServerSocket s = new ServerSocket()) {
s.bind(new InetSocketAddress(config.httpHost(), port)); // throws if occupied
} catch (BindException e) {
throw new IllegalStateException("Port " + port + " already in use — stop the other process or use port 0");
} Prevention
- Use quarkus.http.port=0 in dev/CI so a free port is auto-picked
- Add a pre-build check that kills stale quarkus:dev processes
- Never hardcode the same port for app and management interfaces
- Monitor for TIME_WAIT/zombie sockets in shared CI runners
When it happens
Trigger: VertxHttpRecorder.startServerAfterFailedLaunch/dev startup calls virtualBootstrap.bind(VIRTUAL_HTTP).sync() and the bind fails: port already occupied, address/interface not resolvable, or permission denied on a privileged port.
Common situations: Another Quarkus instance or process (often a stale dev-mode process) is still holding the virtual http port; quarkus.http.* / management port misconfigured in application.properties; running in a container or CI where the configured bind address is unavailable; the thread was interrupted during bind.
Related errors
- CDI container is not available, cannot initialize HTTP Secur
- Failed to start Quarkus
- Quarkus failed to start up
- Unable to find top command. Ensure you have a @CommandDefini
- Quarkus initialization error
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/7b3b04550b58b574.
Report an issue: GitHub.