Kong's internal DNS client fails to resolve a service/container literally named `web`
Summary
Kong's internal DNS client fails to resolve a container literally named
web and falls back to its BAD_ADDRESS placeholder (127.0.53.53),
even though the OS-level resolver on the same container resolves it
correctly, and Kong resolves every other hostname on the same network
without issue. Reproduced on two unrelated hosts/platforms with an
otherwise-identical minimal setup — only the container name differs.
Kong version
kong:3.7 (Docker image), confirmed kong/3.7.1 via the Via response
header. DB-less mode (KONG_DATABASE: "off"), declarative config only,
no plugins involved in the failing route.
Platforms tested (both reproduce identically)
Platform A — Docker Desktop for Mac
- macOS 26.5.2 (BuildVersion 25F84), Apple Silicon (darwin/arm64)
- Docker Desktop 4.82.0, Engine 29.6.1, API 1.55
- Docker Compose v5.3.0
Platform B — native Linux
- Rocky Linux 10.2 (Red Quartz)
- Docker Engine (Community) 29.7.1, API 1.55
- Docker Compose v5.4.0
Testing on a second, architecturally-unrelated platform (native Linux Engine vs. Docker Desktop's VM-based networking) was specifically to rule out a Docker-Desktop-for-Mac networking quirk as the cause. It isn't one — the failure is identical on both.
Current behavior
A Kong Service whose url host is the literal string web fails
every request with a 502 Bad Gateway:
{"message":"An invalid response was received from the upstream server","request_id":"..."}Kong's error log shows it never actually reached the container — it substituted its internal DNS-failure placeholder address:
[error] connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.1, server: kong, request: "GET /web/ HTTP/1.1", upstream: "http://127.0.53.53:80/", host: "localhost:8000", request_id: "..."An otherwise byte-for-byte identical Service/Route pointing at a
container named other (same image, same port, same route shape)
works correctly on the same Kong instance, at the same time.
Expected behavior
Kong resolves web the same way it resolves any other valid hostname
on the network, since it is one.
Steps to reproduce (minimal, ~10 lines of config)
docker-compose.yml:
name: kong-web-dns-repro
services:
kong-config-render:
image: alpine:3.20
volumes:
- ./kong.yml:/kong.yml:ro
- kong-config:/out
entrypoint: ["sh", "-c", "cp /kong.yml /out/kong.yml"]
kong:
image: kong:3.7
environment:
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /kong/kong.yml
KONG_PROXY_LISTEN: "0.0.0.0:8000"
KONG_ADMIN_LISTEN: "0.0.0.0:8001"
volumes:
- kong-config:/kong:ro
ports:
- "8000:8000"
- "8001:8001"
depends_on:
kong-config-render:
condition: service_completed_successfully
web:
condition: service_started
other:
condition: service_started
web:
image: nginx:alpine
other:
image: nginx:alpine
volumes:
kong-config:kong.yml:
_format_version: "3.0"
_transform: true
services:
- name: web
url: http://web:80
routes:
- name: web-route
paths:
- /web
strip_path: true
- name: other
url: http://other:80
routes:
- name: other-route
paths:
- /other
strip_path: truedocker compose up -d
curl -v http://localhost:8000/other/ # 200 OK, nginx welcome page
curl -v http://localhost:8000/web/ # 502, "invalid response... upstream": "http://127.0.53.53:.../"Additional diagnosis (from the original, larger project this was first found in)
Before reducing it to the minimal case above, we ruled out every environment-specific explanation we could think of, on Platform A:
- Not a config-parsing issue —
GET /services/webandGET /services/<working-service>via Kong's Admin API returned identically-structured objects (sameport,protocol,retries,connect_timeout, etc.), differing only inname/host/id. - Not the OS resolver —
getent hosts webinside the Kong container correctly resolved to the container's real IP. Kong's own (separate, non-glibc) DNS client is what fails. - Not a stale
/etc/hostsentry — checked directly, only contained Kong's own loopback/self entries. - Not a competing Docker network or duplicate/orphaned container —
docker network ls/docker inspectshowed Kong on exactly one network with clean aliases;docker ps -ashowed exactly one container namedweb. - Not a transient DNS cache — the failure was 100% reproducible
across many requests and survived a full
docker compose restart kong(a fresh container, fresh DNS client state). - Confirmed it's specifically DNS resolution of that string, not a
response-format issue from the app itself — the target app (a plain
Go
net/httpserver) responded correctly when curled directly inside its own container, and pointing Kong's declarative config directly at the container's raw IP (bypassing hostname resolution entirely) fixed the request immediately.
Workaround
Renaming the container/Compose-service (and correspondingly the
url host in Kong's declarative config) from web to anything else —
we used webui — resolves it completely. The public-facing Kong route
path can stay whatever it was; only the upstream hostname needs to
change.
Why this seems worth reporting
- It's silent and surprising: nothing about the declarative config is invalid, so there's no validation error — just a 502 with a generic message, and the actual cause (Kong's own DNS client, not the app, not Docker's DNS) isn't obvious from anything Kong reports.
webis an extremely common service name in Docker Compose projects, so this likely affects more people than have tracked it down to this specific cause.- It's fully reproducible in under 10 lines of config on two unrelated platforms, which suggests a real bug in Kong's DNS client rather than an environmental fluke.
Source: Kong/kong