One line in a release note — "the minimum supported Engine API version is now 1.44" — and a chunk of the self-hosted Docker ecosystem stopped talking to its own daemon overnight. No CVE, no exploit, no deprecation warning window most people noticed. Docker Engine v29 shipped on November 6, 2025, and any client still asking for an older API version got the same blunt refusal: client version 1.41 is too old. Minimum supported API version is 1.44.
That error hit Portainer, CapRover, Traefik, Watchtower, Dockge, and CasaOS — different tools, different codebases, the same root cause. Here's exactly which ones fixed it, which ones didn't, and what the six-week gap between "instant fix" and "still broken" actually measured.
The break, tool by tool
Every one of these tools talks to the Docker daemon over its HTTP API, and every API request carries a client version number the daemon checks against its own supported range. Docker Engine v29 narrowed that range's floor to 1.44 — anything below it gets rejected before the request even runs. The tools that had that version number hardcoded instead of queried at runtime broke the instant their host upgraded:
| Tool | API version in use | What broke | Fix shipped |
|---|---|---|---|
| Portainer | pre-2.33.5 hardcoded to 1.41 | Environments failed to load, all Docker calls errored | 2.33.5 (LTS) / 2.36.0 (STS) — added runtime API negotiation |
| CapRover | pinned to 1.43 via docker-modem | captain-captain failed to start; dashboard down | 1.14.1 hotfix, days after the v29 release |
| Traefik | hardcoded 1.24 in the Docker provider | Reverse-proxy routing stopped picking up new containers | v3.6.1 (Nov 13–14, 2025) via PR #12256 — negotiates against the daemon instead of a fixed version |
| Watchtower | hardcoded 1.25, project effectively unmaintained | Every update check failed in a loop | None. GitHub discussions ask openly whether the project is dead |
| CasaOS | compiled against 1.43 | App Store manager and dashboard stopped listing containers | No comprehensive fix confirmed as of this writing; the issue is still open |
| Dockge | 1.41 (per a since-filed compatibility issue) | Backend refused to connect to the daemon | No dedicated v29 fix found; a stagnation issue about the bundled Docker client had already been open since January 2025 — nine months before v29 shipped |
Two tools deserve a caveat instead of a verdict. Yacht is often lumped into this list, but its GitHub org shows active 2026 commits — a multi-host feature and a backend rewrite in progress — so "broken and abandoned" doesn't hold up; there's just no public evidence either way of a specific API-negotiation fix, which is its own kind of answer. Swarmpit, sometimes cited alongside these, has no confirmed 2025–2026 release at all, which puts it past "broken" into "not being shipped."
The pattern in the confirmed cases is not subtle: Portainer, CapRover, and Traefik went from broken to fixed in single-digit days to a couple of weeks. Watchtower, Dockge, and CasaOS are still sitting on open issues months later.
Why the "fixed" list fixed itself so fast
The fast fixes share one technical trait: they stopped hardcoding a version number and started asking the daemon what it supports.
Traefik's PR #12256 is the cleanest example. Before it, the Docker provider sent every request stamped API-Version: 1.24 — a number chosen years earlier and never revisited. After it, Traefik calls docker version on startup, reads the daemon's actual supported range, and picks the highest version both sides agree on. That's the same fix Portainer shipped in 2.33.5/2.36.0 and the same shape CapRover's docker-modem bump made possible. None of these are hard changes — version negotiation against a daemon you're already connected to is a few lines of code — but someone has to notice the floor moved and ship the few lines.
Watchtower's client is still stamped 1.25 not because negotiation is hard, but because there's been no maintainer actively cutting releases to ship it. Dockge's bundled Docker client had already drifted a full major version behind apt's available release nine months before v29 shipped — the compatibility gap was visible in a filed issue well before the vendor forced the question. CasaOS's dashboard has an open issue and no shipped resolution. In each case the missing ingredient wasn't engineering difficulty — it was someone watching upstream release notes closely enough to act before a user's daemon upgrade did it for them.
An involuntary maintenance-liveness test
Docker didn't ship this as a feature aimed at any of these projects. Raising the minimum API version was routine housekeeping — the kind every actively developed runtime does periodically to drop support for API surface nobody recent still needs. But routine housekeeping from a vendor that sits underneath an entire ecosystem doubles as something else: a forced, simultaneous test of which downstream projects are still being actively watched.
A security patch gets triaged with urgency because someone is scanning for CVEs. A missing feature gets requested and, eventually, built. But "the floor moved" produces no CVE and satisfies no feature request — it just silently breaks anything hardcoded, on whatever schedule the user's host happens to upgrade on, with zero signal to the project maintainer unless they're already reading Docker's own release notes. Every project on the "still broken" side of that table had the same option every project on the "fixed" side had: watch the notes, ship a point release, negotiate the version instead of pinning it. The tools that did are the tools somebody was still driving. The v29 API bump didn't create that gap — it just made it visible to every user in the same week, instead of leaving it to surface one bug report at a time.
And the pace hasn't slowed since: Docker has shipped roughly a release a month past v29.0 — the latest, 29.6.2, landed July 16, 2026 — including a 29.5.1 security release that patched multiple docker cp vulnerabilities. Anyone still hardcoding an API version today is one more point release away from repeating this exact incident.
What it means for a fleet that owns its own nodes
A self-hosted PaaS running on Cluster API-managed hardware has the same exposure these tools did, just one layer down: every provisioned node's image bakes in a specific Docker Engine (or containerd) version, and every service that talks to that daemon — the scheduler, the deploy agent, any sidecar shelling out to docker — carries an assumption about what API surface it can rely on.
The lesson from this table isn't "pin a version and never touch it" — pinning is exactly what broke Watchtower, CapRover, and Dockge. It's that the pin has to be a tracked, revisited decision, not a value written once and forgotten:
- Negotiate, don't hardcode. Any internal tooling that talks to the Docker/containerd API directly should query the daemon's supported range at connection time, the same fix Traefik and Portainer shipped, rather than stamping a version chosen when the code was first written.
- Track the floor, not just the CVEs. A subscription to Docker's engine release notes catches "minimum supported API version" language before a node-image bump ships it into production, the same way a CVE feed catches security issues — this class of break just doesn't show up in a CVE feed at all.
- Test the next major before it's the running version. CapRover's fix landed in days because someone was already paying attention when v29 shipped; a fleet that runs its own node images can go further and smoke-test a staging node against a new Docker major before rolling it into the pool that production traffic depends on.
None of that is exotic — it's the same operational discipline a Cluster API-based platform already applies to node OS patching. Docker's API floor is just one more moving part in that same pipeline, and this incident is the reminder that it doesn't stay still on its own schedule.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with a node-image pipeline that tracks its own runtime dependencies instead of hardcoding them and finding out later. Star the repo on GitHub or deploy your first app today.
Sources
- Docker Engine version 29 release notes
- Docker v29, and the fall-out
- Portainer 2.33.3 fails to connect to Docker 29.x due to strict minimum API version check (GitHub issue)
- IMPORTANT: Docker API Breaking Changes!!! caprover/caprover failing to start (GitHub issue)
- Docker 29 Broke Traefik — Here's the Fix (and Why It Happened)
- Auto-negotiate Docker API Version (Traefik PR #12256)
- Watchtower seems to be dead and is no longer being developed? (GitHub discussion)
- Docker Engine Client and Docker Compose Version Stagnated (Dockge GitHub issue #707)
- client version 1.53 is too new. Maximum supported API version is 1.41 (Dockge GitHub issue #935)
- Bug: Docker 5.29 update breaking CasaOS Web UI for apps (GitHub issue)



