#14970·kong

Kong's internal DNS client fails to resolve a service/container literally named `web`

Author: ajpippinCreated Aug 8, 2026Updated Aug 14, 2026

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:

json
{"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:

yaml
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:

yaml
_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: true
bash
docker 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 issueGET /services/web and GET /services/<working-service> via Kong's Admin API returned identically-structured objects (same port, protocol, retries, connect_timeout, etc.), differing only in name/host/id.
  • Not the OS resolvergetent hosts web inside 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/hosts entry — checked directly, only contained Kong's own loopback/self entries.
  • Not a competing Docker network or duplicate/orphaned containerdocker network ls / docker inspect showed Kong on exactly one network with clean aliases; docker ps -a showed exactly one container named web.
  • 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/http server) 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.
  • web is 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.