Improvements and Fixes
- Clone major upgrade no longer fails at the check stage on instances that mount TLS certificates or other files into clones: the upgrade container now gets the volumes from
databaseContainer.containerConfig (!1206, #792)
- The "Upgrade clone" button stays visible when clone upgrade is unavailable (for example,
provision.pgUpgradeImage is not set); it is disabled and shows the engine's reason in a tooltip (!1205)
- Creating a clone for a restricted user no longer fails with
cannot alter partition ... with an incomplete detach when the snapshot holds a partition with a pending DETACH PARTITION ... CONCURRENTLY; the detach is finalized in the clone (!1208, #795)
- Clone state (
sessions.json) is written atomically, and the engine refuses to start on an unreadable state file; a crash in the middle of a write could previously lead to every clone being destroyed on the next start (!1198, #783)
- A panic in a background job or an HTTP handler no longer terminates the engine, and data races in WebSocket token cleanup and webhook reload are fixed (!1198, !1199, #783, #784)
- Config reload is synchronized across engine services, fixing data races between a reload and in-flight requests; two concurrent full refreshes can no longer both start, and a clone being provisioned keeps its database config across a reload (!1202, #788)
- A rotated
verificationToken takes effect on config reload instead of requiring a restart (!1199, #29)
- A Postgres start timeout is reported as an error instead of success, and
POST /observation/stop no longer hangs when the observation session ended with an error (!1199, #784)
- The pool is activated and branching is initialized when there are no retrieval jobs or the snapshot already exists (!1199, #784)
--extra-config and --tags values without = make dblab return an error instead of panicking (!1199, #784)
- Not-found and bad-request API errors return 404/400 instead of 500; percent-encoded snapshot IDs are accepted;
POST /snapshot returns the snapshot model with correct sizes; an empty deleteAt is rejected with 400; the log of a branch named snapshot is reachable (!1197, #782)
- The OpenAPI spec matches the engine's routes and models, including 7 previously undocumented operations (!1196)
- The Logs tab no longer leaks WebSocket connections and auto-scrolls again, and a render error shows a message instead of a blank page (!1203, #787)
Security
- An empty
provision.upgradeImageAllowList now allows clone upgrades only to images from the repository of the clone image instead of any repository; set ["*"] to restore the previous behavior (breaking change of the default) (!1200, #786)
- Host, user, database and table names are shell-quoted in logical dump and restore commands (!1200, #786)
- Physical-mode
envs values (WAL-G and pgBackRest credentials) are masked in the config view and in GET /admin/config; the configuration editor keeps the stored values on save (!1200, #786)
- The HTTP server has read and idle timeouts and a 1 MiB request body limit (413
PAYLOAD_TOO_LARGE), and the API client applies a request timeout (!1200, #786)
- Binaries are built with Go 1.26.8 (up from 1.26.7), and
golang.org/x/crypto is bumped to v0.57.0 (!1201)
moment is bumped to 2.31.0 (CVE-2026-17495) and dompurify to 3.4.16, with raised floors for fast-uri, brace-expansion, browserslist, js-yaml and other transitive UI dependencies (!1210)
Internal
- Release tags are gated on the e2e matrix (PG 10-18) and the integration suite; publish jobs run only after the tests pass (!1201)
- ESLint and unit tests run for every UI package, including
@postgres.ai/shared (!1203, #787)
Full diff
Diff between versions 4.2.0 and 4.2.1