I have run into an issue where Keycloak reports that the port it is attempting to start the http server on is already in use:
- The port in question is the http port, which I’ve set using the
KC_HTTP_PORT
environment variable, although it is the default of8080
. - I’ve also tried changing the port, with the same result. - I’ve verified that none of the ports I’ve attempted to use are in use on the host, using
lsof -nP -iTCP -sTCP:LISTEN
; the only time anything is listening on these ports is when I start the container. - I have run into the same issue using a standard/prebuild container (
quay.io/keycloak/keycloak:26.2
) and with a customized build.
It’s beyond me, at this point, where the issue lies and I would welcome any thoughts on potential causes.
My Docker compose:
services:
postgres:
container_name: keycloak-database
hostname: keycloak-database
image: postgres:17-alpine
env_file:
- .env
environment:
POSTGRES_DB: ${KC_DB_URL_DATABASE}
POSTGRES_USER: ${KC_DB_USERNAME}
POSTGRES_PASSWORD: ${KC_DB_PASSWORD}
POSTGRES_PORT: ${KC_DB_URL_PORT}
TZ: America/New_York
volumes:
- /docker/data/keycloak/pg_data:/var/lib/postgresql/data/
ports:
- 5432:5432
healthcheck:
test: [ "CMD", "pg_isready", "-q", "-d", "keycloak_db", "-U", "keycloak" ]
interval: 30s
timeout: 5s
retries: 3
start_period: 5s
restart: unless-stopped
keycloak:
container_name: keycloak-server
hostname: keycloak-server
env_file:
- .env
build:
dockerfile: Dockerfile
args:
KC_HEALTH_ENABLED: ${KC_HEALTH_ENABLED}
KC_METRICS_ENABLED: ${KC_METRICS_ENABLED}
KC_HOSTNAME: ${KC_HOSTNAME}
KC_HOSTNAME_ADMIN: ${KC_HOSTNAME_ADMIN}
KC_DB: ${KC_DB_VENDOR}
KC_DB_URL_HOST: ${KC_DB_URL_HOST}
KC_DB_URL_DATABASE: ${KC_DB_URL_DATABASE}
KC_DB_URL_PORT: ${KC_DB_URL_PORT}
KC_DB_USERNAME: ${KC_DB_USERNAME}
KC_DB_PASSWORD: ${KC_DB_PASSWORD}
KC_DB_SCHEMA: ${KC_DB_SCHEMA}
KC_HTTP_ENABLED: ${KC_HTTP_ENABLED}
KC_HTTP_HOST: ${KC_HTTP_HOST}
KC_HTTP_PORT: ${KC_HTTP_PORT}
KC_HTTP_MAX_QUEUED_REQUESTS: ${KC_HTTP_MAX_QUEUED_REQUESTS}
KC_HTTP_RELATIVE_PATH: ${KC_HTTP_RELATIVE_PATH}
KC_PROXY_HEADERS: ${KC_PROXY_HEADERS}
KC_PROXY_TRUSTED_ADDRESSES: ${KC_PROXY_TRUSTED_ADDRESSES}
KC_BOOTSTRAP_ADMIN_USERNAME: ${KC_BOOTSTRAP_ADMIN_USERNAME}
KC_BOOTSTRAP_ADMIN_PASSWORD: ${KC_BOOTSTRAP_ADMIN_PASSWORD}
# image: quay.io/keycloak/keycloak:26.2
depends_on:
postgres:
condition: service_healthy
environment:
KC_VERSION: ${KC_VERSION}
KC_HEALTH_ENABLED: ${KC_HEALTH_ENABLED}
KC_METRICS_ENABLED: ${KC_METRICS_ENABLED}
KC_HOSTNAME: ${KC_HOSTNAME}
KC_HOSTNAME_ADMIN: ${KC_HOSTNAME_ADMIN}
KC_DB: ${KC_DB_VENDOR}
KC_DB_URL_HOST: ${KC_DB_URL_HOST}
KC_DB_URL_PORT: ${KC_DB_URL_PORT}
KC_DB_URL_DATABASE: ${KC_DB_URL_DATABASE}
KC_DB_USERNAME: ${KC_DB_USERNAME}
KC_DB_PASSWORD: ${KC_DB_PASSWORD}
KC_PROXY_HEADERS: ${KC_PROXY_HEADERS}
KC_PROXY_TRUSTED_ADDRESSES: ${KC_PROXY_TRUSTED_ADDRESSES}
KC_HTTP_ENABLED: ${KC_HTTP_ENABLED}
KC_HTTP_HOST: ${KC_HTTP_HOST}
KC_HTTP_PORT: ${KC_HTTP_PORT}
KC_HTTP_MAX_QUEUED_REQUESTS: ${KC_HTTP_MAX_QUEUED_REQUESTS}
KC_HTTP_RELATIVE_PATH: ${KC_HTTP_RELATIVE_PATH}
KC_BOOTSTRAP_ADMIN_USERNAME: ${KC_BOOTSTRAP_ADMIN_USERNAME}
KC_BOOTSTRAP_ADMIN_PASSWORD: ${KC_BOOTSTRAP_ADMIN_PASSWORD}
volumes:
- /docker/data/keycloak/kc_data:/data
ports:
- 8080:8080 # http
- 9000:9000 # management interface
Dockerfile:
ARG KC_VERSION=26.2
FROM quay.io/keycloak/keycloak:${KC_VERSION} AS builder
ARG KC_VERSION
ARG KC_HEALTH_ENABLED
ARG KC_METRICS_ENABLED
ARG KC_HOSTNAME
ARG KC_HOSTNAME_ADMIN
ARG KC_DB
ARG KC_DB_URL_HOST
ARG KC_DB_URL_DATABASE
ARG KC_DB_URL_PORT
ARG KC_DB_USERNAME
ARG KC_DB_PASSWORD
ARG KC_DB_SCHEMA
ARG KC_PROXY_HEADERS
ARG KC_PROXY_TRUSTED_ADDRESSES
ARG KC_HTTP_ENABLED
ARG KC_HTTP_HOST
ARG KC_HTTP_PORT
ARG KC_HTTP_MAX_QUEUED_REQUESTS
ARG KC_HTTP_RELATIVE_PATH
ARG KC_BOOTSTRAP_ADMIN_USERNAME
ARG KC_BOOTSTRAP_ADMIN_PASSWORD
ENV KC_HEALTH_ENABLED ${KC_HEALTH_ENABLED}
ENV KC_METRICS_ENABLED ${KC_METRICS_ENABLED}
ENV KC_HOSTNAME ${KC_HOSTNAME}
ENV KC_HOSTNAME_ADMIN ${KC_HOSTNAME_ADMIN}
ENV KC_DB ${KC_DB}
ENV KC_DB_URL_HOST ${KC_DB_URL_HOST}
ENV KC_DB_URL_PORT ${KC_DB_URL_PORT}
ENV KC_DB_URL_DATABASE ${KC_DB_URL_DATABASE}
ENV KC_DB_USERNAME ${KC_DB_USERNAME}
ENV KC_DB_PASSWORD ${KC_DB_PASSWORD}
ENV KC_DB_SCHEMA ${KC_DB_SCHEMA}
ENV KC_PROXY_HEADERS ${KC_PROXY_HEADERS}
ENV KC_PROXY_TRUSTED_ADDRESSES ${KC_PROXY_TRUSTED_ADDRESSES}
ENV KC_HTTP_ENABLED ${KC_HTTP_ENABLED}
ENV KC_HTTP_HOST ${KC_HTTP_HOST}
ENV KC_HTTP_PORT ${KC_HTTP_PORT}
ENV KC_HTTP_MAX_QUEUED_REQUESTS ${KC_HTTP_MAX_QUEUED_REQUESTS}
ENV KC_HTTP_RELATIVE_PATH ${KC_HTTP_RELATIVE_PATH}
ENV KC_BOOTSTRAP_ADMIN_USERNAME ${KC_BOOTSTRAP_ADMIN_USERNAME}
ENV KC_BOOTSTRAP_ADMIN_PASSWORD ${KC_BOOTSTRAP_ADMIN_PASSWORD}
WORKDIR /opt/keycloak
# for demonstration purposes only, please make sure to use proper certificates in production instead
#RUN keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore conf/server.keystore
RUN /opt/keycloak/bin/kc.sh build
FROM quay.io/keycloak/keycloak:${KC_VERSION}
COPY --from=builder /opt/keycloak/ /opt/keycloak/
ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start"]
.env:
KC_DB_VENDOR=postgres
KC_DB_USERNAME=keycloak
KC_DB_PASSWORD=my-password
KC_DB_URL_HOST=keycloak-database
KC_DB_URL_DATABASE=keycloak_db
KC_DB_URL_PORT=5432
KC_DB_SCHEMA=public
KC_VERSION=26.2
KC_HOSTNAME=auth.my.tld
KC_HOSTNAME_ADMIN=auth-admin.my.tld
KC_HEALTH_ENABLED=true
KC_METRICS_ENABLED=true
KC_BOOTSTRAP_ADMIN_USERNAME=admin-username
KC_BOOTSTRAP_ADMIN_PASSWORD=admin-password
KC_PROXY_HEADERS=xforwarded
KC_PROXY_TRUSTED_ADDRESSES=10.0.0.0/8
KC_HTTP_ENABLED=true
KC_HTTP_HOST=0.0.0.0
KC_HTTP_PORT=8080
KC_HTTP_MAX_QUEUED_REQUESTS=10
KC_HTTP_RELATIVE_PATH="/"
And, the logs:
root@dmh-auth-kc0:/docker/compose/keycloak# docker compose up -d && docker logs --follow keycloak-server
[+] Running 3/3
✔ Network keycloak_keycloak_network Created 0.1s
✔ Container keycloak-database Healthy 6.2s
✔ Container keycloak-server Started 6.2s
2025-05-07 21:39:46,815 INFO [org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory] (main) Starting Infinispan embedded cache manager
2025-05-07 21:39:46,836 INFO [org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory] (main) JGroups JDBC_PING discovery enabled.
2025-05-07 21:39:47,484 INFO [org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory] (main) JGroups Encryption enabled (mTLS).
2025-05-07 21:39:48,084 INFO [org.keycloak.infinispan.module.certificates.CertificateReloadManager] (main) Starting JGroups certificate reload manager
2025-05-07 21:39:48,734 INFO [org.infinispan.CONTAINER] (main) ISPN000556: Starting user marshaller 'org.infinispan.commons.marshall.ImmutableProtoStreamMarshaller'
2025-05-07 21:39:49,581 INFO [org.infinispan.CLUSTER] (main) ISPN000078: Starting JGroups channel `ISPN` with stack `jdbc-ping`
2025-05-07 21:39:49,586 INFO [org.jgroups.JChannel] (main) local_addr: 6ad55e9c-3905-430e-8109-c3b81c0dad0a, name: keycloak-server-41060
2025-05-07 21:39:49,607 INFO [org.jgroups.protocols.FD_SOCK2] (main) server listening on *:57800
2025-05-07 21:39:49,632 INFO [org.jgroups.protocols.pbcast.GMS] (main) keycloak-server-41060: no members discovered after 19 ms: creating cluster as coordinator
2025-05-07 21:39:49,772 INFO [org.infinispan.CLUSTER] (main) ISPN000094: Received new cluster view for channel ISPN: [keycloak-server-41060|0] (1) [keycloak-server-41060]
2025-05-07 21:39:49,784 INFO [org.keycloak.infinispan.module.certificates.CertificateReloadManager] (main) Reloading JGroups Certificate
2025-05-07 21:39:49,970 INFO [org.infinispan.CLUSTER] (main) ISPN000079: Channel `ISPN` local address is `keycloak-server-41060`, physical addresses are `[172.19.0.3:7800]`
2025-05-07 21:39:51,841 INFO [org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory] (main) Node name: keycloak-server-41060, Site name: null
2025-05-07 21:39:55,480 INFO [org.infinispan.CLUSTER] (main) ISPN000080: Disconnecting JGroups channel `ISPN`
2025-05-07 21:39:55,507 INFO [org.keycloak.infinispan.module.certificates.CertificateReloadManager] (main) Stopping JGroups certificate reload manager
2025-05-07 21:39:55,529 INFO [com.arjuna.ats.jbossatx] (main) ARJUNA032014: Stopping transaction recovery manager
2025-05-07 21:39:55,607 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: Failed to start server in (production) mode
2025-05-07 21:39:55,609 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) Error details:: java.lang.RuntimeException: Unable to start HTTP server
at io.quarkus.vertx.http.runtime.VertxHttpRecorder.doServerStart(VertxHttpRecorder.java:997)
at io.quarkus.vertx.http.runtime.VertxHttpRecorder.startServer(VertxHttpRecorder.java:371)
at io.quarkus.runner.recorded.VertxHttpProcessor$openSocket1873327713.deploy_0(Unknown Source)
at io.quarkus.runner.recorded.VertxHttpProcessor$openSocket1873327713.deploy(Unknown Source)
at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
at io.quarkus.runtime.Application.start(Application.java:101)
at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:121)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:77)
at org.keycloak.quarkus.runtime.KeycloakMain.start(KeycloakMain.java:145)
at org.keycloak.quarkus.runtime.cli.Picocli.start(Picocli.java:1000)
at org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.run(AbstractStartCommand.java:49)
at picocli.CommandLine.executeUserObject(CommandLine.java:2030)
at picocli.CommandLine.access$1500(CommandLine.java:148)
at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2465)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2457)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2419)
at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2277)
at picocli.CommandLine$RunLast.execute(CommandLine.java:2421)
at picocli.CommandLine.execute(CommandLine.java:2174)
at org.keycloak.quarkus.runtime.cli.Picocli.parseAndRun(Picocli.java:128)
at org.keycloak.quarkus.runtime.KeycloakMain.main(KeycloakMain.java:116)
at org.keycloak.quarkus.runtime.KeycloakMain.main(KeycloakMain.java:71)
at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:68)
at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:36)
Caused by: java.util.concurrent.ExecutionException: io.quarkus.runtime.QuarkusBindException: Port(s) already bound: 8080: Cannot assign requested address
at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:396)
at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2073)
at io.quarkus.vertx.http.runtime.VertxHttpRecorder.doServerStart(VertxHttpRecorder.java:914)
... 23 more
Caused by: io.quarkus.runtime.QuarkusBindException: Port(s) already bound: 8080: Cannot assign requested address
at io.quarkus.vertx.http.runtime.VertxHttpRecorder$13.handle(VertxHttpRecorder.java:881)
at io.quarkus.vertx.http.runtime.VertxHttpRecorder$13.handle(VertxHttpRecorder.java:862)
at io.vertx.core.impl.future.FutureImpl$4.onFailure(FutureImpl.java:188)
at io.vertx.core.impl.future.FutureBase.emitFailure(FutureBase.java:81)
at io.vertx.core.impl.future.FutureImpl.tryFail(FutureImpl.java:278)
at io.vertx.core.impl.future.Mapping.onFailure(Mapping.java:45)
at io.vertx.core.impl.future.FutureBase.emitFailure(FutureBase.java:81)
at io.vertx.core.impl.future.FutureImpl.tryFail(FutureImpl.java:278)
at io.vertx.core.impl.future.PromiseImpl.onFailure(PromiseImpl.java:54)
at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:43)
at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:23)
at io.vertx.core.impl.DeploymentManager.lambda$reportResult$2(DeploymentManager.java:129)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:270)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:252)
at io.vertx.core.impl.ContextInternal.lambda$runOnContext$0(ContextInternal.java:50)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1583)