#26558·cosmos-sdk

baseapp: BaseApp.Close is not idempotent — double app.Close() on shutdown panics with PebbleDB ("pebble: closed")

Author: MirageFoundationCreated Jun 27, 2026Updated Jun 27, 2026

What happened: Every graceful shutdown panics FATAL: panic: pebble: closed at the tail end (after an otherwise-clean stop), exiting the process non-zero.

Root cause: server/start.go startInProcess registers two deferred cleanups that both call app.Close() — startCmtNode's cleanupFn (after tmNode.Stop()) and startApp's appCleanupFn. baseapp.(*BaseApp).Close() closes app.db unconditionally, so the second call re-closes the already-closed DB. PebbleDB panics pebble: closed on a second Close(); other backends (e.g. MemDB/GoLevelDB) silently tolerate it, which is why it's easy to miss.

Affected: main and release/v0.54.x (baseapp.go Close + server/start.go are identical there).

Impact: non-zero exit on every shutdown; noise that masks genuine Close() errors and pollutes crash monitoring. Cosmetic for the DB itself (the first close is clean) but real for ops.

Fix: make BaseApp.Close() idempotent (clear app.db / app.snapshotManager after closing). PR + regression test attached.