Skip to content

supabase db reset can leave Kong routing to a stale container IP, causing 502 on /auth/v1/* #6016

Description

@AlbinoGeek

Affected area

Local development

Supabase CLI version

2.110.0

Operating system

Fedora Linux 44 (kernel 7.1.4-204.fc44.x86_64)

Installation method

brew

Command

supabase db reset

Actual output

# The reset itself reports success and exits 0:
Resetting local database...
Recreating database...
Initialising schema...
Seeding globals from roles.sql...
Restarting containers...
Finished supabase db reset on branch main.

# But the auth route through Kong is now dead, and stays dead:
$ curl -o /dev/null -w '%{http_code}\n' http://127.0.0.1:54321/auth/v1/health
502

# Any /auth/v1 request fails the same way. A seed script creating the local admin
# through the admin API got the body form:
#   could not create <address>: 502 {
#     "message":"An invalid response was received from the upstream server"
#   }

# Kong is dialling an address the auth container no longer holds
# (auth was on 172.18.0.8 at this point):
$ docker logs supabase_kong_<project>
[error] 1110#0: *4461 connect() failed (111: Connection refused) while connecting to upstream,
  client: 172.18.0.1, server: kong, request: "GET /auth/v1/health HTTP/1.1",
  upstream: "http://172.18.0.4:9999/health", host: "127.0.0.1:54321"

# GoTrue itself is healthy and answers on its real address:
$ docker inspect -f '{{.State.Health.Status}}' supabase_auth_<project>
healthy
$ curl -o /dev/null -w '%{http_code}\n' http://172.18.0.8:9999/health
200

# Restarting Kong is the only thing that clears it:
$ docker restart supabase_kong_<project>
$ curl -o /dev/null -w '%{http_code}\n' http://127.0.0.1:54321/auth/v1/health
200

Expected behavior

supabase db reset should leave the local stack fully routable.

Any container the reset restarts should either keep a stable address, or Kong should be
restarted (or made to re-resolve its upstreams) as part of the same operation, so that
/auth/v1/* keeps working once the command reports success.

Today the command exits 0 and supabase status reports every container healthy — because
each container individually is healthy — while requests through the gateway return 502.

Steps to reproduce

Root cause first, because it explains why the reset-driven repro is intermittent:

Kong addresses its upstreams by container hostname and caches the resolved address for the
life of its process:

url: http://supabase_auth_<project>:9999/
url: http://supabase_storage_<project>:5000/

supabase db reset recreates the db container and restarts auth, realtime and storage, but
never restarts kong. Docker assigns addresses from a free pool on start, so a restarted
container can return on a different address. auth and storage are stopped and started
together, so whichever starts first takes the lower free address; when that order flips
between resets the two swap, and Kong's cached value is then wrong. It does not recover on
its own — Kong has to be restarted.

Intermittent path (what a user actually hits):

  1. supabase start, wait for all containers healthy.
  2. curl -o /dev/null -w '%{http_code}\n' http://127.0.0.1:54321/auth/v1/health → 200
  3. Run supabase db reset.
  4. Repeat 2-3. On the resets where the start order flips, step 2 returns 502 and keeps
    returning 502 until kong is restarted.

Deterministic path (forces the address change directly, no reset needed — substitute your
project suffix for ):

  1. supabase start, wait for all containers healthy.
  2. Confirm the route works:
    curl -o /dev/null -w '%{http_code}\n' http://127.0.0.1:54321/auth/v1/health # 200
  3. Make auth and storage exchange addresses:
    docker stop supabase_auth_ supabase_storage_
    docker start supabase_storage_ # takes the address auth just released
    docker start supabase_auth_ # lands on a different one
  4. Confirm they swapped:
    docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' supabase_auth_
    docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' supabase_storage_
  5. The route is now broken and stays broken:
    curl -o /dev/null -w '%{http_code}\n' http://127.0.0.1:54321/auth/v1/health # 502
  6. docker restart supabase_kong_<project> restores it.

Step 5 reproduced on the first attempt. Container names never change in any of this — only
the addresses behind them.

Crash report ID

No response

Docker and service versions

$ docker version
Client: Docker Engine - Community
 Version:           29.6.2
 API version:       1.55
Server: Docker Engine - Community
  Version:          29.6.2
  API version:      1.55 (minimum version 1.40)

# `supabase services`, as emitted when piped (local versions only, remote omitted):
supabase/postgres        17.6.1.143
supabase/gotrue          v2.193.0
postgrest/postgrest      v14.15
supabase/realtime        v2.113.4
supabase/storage-api     v1.66.4
supabase/edge-runtime    v1.74.2
supabase/studio          2026.07.13-sha-b5ada96
supabase/postgres-meta   v0.96.6
supabase/logflare        1.47.1
supabase/supavisor       2.9.7

Additional context

Evidence that kong is the container the reset leaves behind

Container identity before and after a single supabase db reset:

BEFORE

/supabase_auth_<p>      id=0f4d55029bc3  started=2026-07-31T01:16:46Z  ip=172.18.0.4
/supabase_db_<p>        id=99b4e26d6a1f  started=2026-07-31T01:16:30Z  ip=172.18.0.2
/supabase_kong_<p>      id=c5ccc88fe58c  started=2026-07-31T01:17:23Z  ip=172.18.0.3
/supabase_realtime_<p>  id=5e135e1136eb  started=2026-07-31T01:16:47Z  ip=172.18.0.6
/supabase_storage_<p>   id=d5c6a2947293  started=2026-07-31T01:16:46Z  ip=172.18.0.8

AFTER

/supabase_auth_<p>      id=0f4d55029bc3  started=2026-07-31T01:19:38Z  ip=172.18.0.4
/supabase_db_<p>        id=4d675b22d679  started=2026-07-31T01:19:22Z  ip=172.18.0.2
/supabase_kong_<p>      id=c5ccc88fe58c  started=2026-07-31T01:17:23Z  ip=172.18.0.3
/supabase_realtime_<p>  id=5e135e1136eb  started=2026-07-31T01:19:39Z  ip=172.18.0.6
/supabase_storage_<p>   id=d5c6a2947293  started=2026-07-31T01:19:38Z  ip=172.18.0.8

db is recreated (container ID changes). auth, realtime and storage are restarted (same ID,
new StartedAt). kong is untouched — its StartedAt is older than the reset that just ran.

On a separate reset the addresses did move, with auth and storage exchanging 172.18.0.4 and
172.18.0.8, which is the state the Kong log in "Actual output" was captured from.

Why this bites tooling in particular

Anything that talks to GoTrue immediately after a reset — a seed script creating a user via
POST /auth/v1/admin/users, for example — fails with a 502 that looks like a transient startup
race but is not, and will not clear no matter how long it waits.

Possible fixes

  • Restart kong alongside the other containers in db reset, so it re-resolves its upstreams.
    Smallest change, and consistent with what the CLI already does for the services it restarts.
  • Give the compose services stable addresses so a restart cannot move them.
  • Configure Kong's DNS caching so a stale upstream record expires quickly rather than
    persisting for the life of the process.

Relationship to #4535

#4535 is closed and reports the same 502 symptom, but
attributes it to Docker Compose appending a folder-name suffix to container names. That
diagnosis does not appear to be correct: the Kong log quoted in that issue is also a stale
IP address, not an unresolved container name, which is the same mechanism described here.

This report reproduces the failure with entirely stable container names, on CLI 2.110.0 —
substantially newer than the 2.62.10 in that issue. The underlying defect therefore still
exists and that thread records the wrong cause.

Note also that SUPABASE_DB_ONLY=true supabase db reset, offered as a workaround in #4535,
does not help on 2.110.0: it still prints "Restarting containers..." and takes the same time,
so the containers still move.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions