quarkusio/quarkus · error · RuntimeException

Failed to start SPIFFE HTTP server

Error message

Failed to start SPIFFE HTTP server

What it means

Companion to the gRPC failure: the SPIFFE dev HTTP server (used to serve JWKS and related endpoints) fails to bind or complete its listen within 20 seconds. startHttpServer() wraps the exception as RuntimeException 'Failed to start SPIFFE HTTP server' and records the cause message in errorMessages.

Source

Thrown at extensions/spiffe-client/deployment/src/main/java/io/quarkus/spiffe/client/deployment/SpiffeDevServicesProcessor.java:400

                        .toCompletableFuture()
                        .get(20, TimeUnit.SECONDS);
            } catch (Exception e) {
                throw new RuntimeException("Failed to start SPIFFE gRPC server on " + transport, e);
            }
        }

        private void startHttpServer() {
            httpServer = vertx.createHttpServer(new HttpServerOptions().setPort(httpPort));
            try {
                httpServer.requestHandler(this::handleHttpRequest)
                        .listen(SocketAddress.inetSocketAddress(httpPort, "127.0.0.1"))
                        .toCompletionStage()
                        .toCompletableFuture()
                        .get(20, TimeUnit.SECONDS);
                LOG.debugf("Started SPIFFE HTTP server on port %s", httpServer.actualPort());
            } catch (Exception e) {
                errorMessages.add("Failed to start SPIFFE HTTP server: " + e.getMessage());
                throw new RuntimeException("Failed to start SPIFFE HTTP server", e);
            }
        }

        @Override
        public String getConnectionInfo() {
            return endpointSocket;
        }

        @Override
        public String getContainerId() {
            return null;
        }
    }

    static final class SpiffeDevServicesEnabled implements BooleanSupplier {

        private final boolean enabled;

View on GitHub (pinned to e1c734241f)

Solutions

  1. Check `Caused by:` for BindException; kill the process holding the port (lsof -i :<port> / netstat).
  2. Remove any fixed quarkus.spiffe-client.devservices.http-port so an ephemeral port is used.
  3. Address 'Address already in use' by setting SO_REUSEPORT-capable alternatives or just changing the port; on CI, stagger parallel module runs (Quarkus does not support parallel test modules).

Example fix

# before
quarkus.spiffe-client.devservices.http-port=15986

# after: ephemeral port (key removed); read the actual port from DevServices logs
# quarkus.spiffe-client.devservices.http-port=<unset>
Defensive patterns

Strategy: retry

Validate before calling

try (var s = new java.net.ServerSocket(httpPort)) { /* port free */ }
catch (java.io.IOException e) { throw new IllegalStateException("http-port " + httpPort + " occupied"); }

Try / catch

try {
    httpServer.listen(httpPort).toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS);
} catch (Exception e) {
    LOG.error("SPIFFE HTTP dev server failed; check Caused by for BindException/timeout", e);
}

Prevention

When it happens

Trigger: startHttpServer() creates a Vert.x HttpServer on the configured httpPort and awaits listen(...).get(20, TimeUnit.SECONDS); failure occurs when the port is already bound (BindException), permissions block binding, or the future times out.

Common situations: Port conflicts with other dev services or a previously crashed instance still holding the port; running two Quarkus dev apps concurrently with the same fixed devservices port; firewall/SELinux restrictions on loopback ports.

Related errors


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