This article is co-authored with a generative AI. Facts have been cross-checked against official documentation where possible, but errors may remain. Please verify against primary sources before making any important decisions.
A Drupal site running on one of our servers became unreachable. On investigation, the cause turned out not to be Drupal itself, but the reverse proxy in front of it โ Traefik โ which could no longer connect to the Docker API. The trigger was a major version bump of the Docker Engine, brought in by a bulk upgrade of packages including ones from a third-party repository. Since this can recur on similar setups, here is a write-up of the investigation, the recovery steps, and what we plan to do to prevent it.
Symptom
A Drupal site was unreachable. It was not an application-level error page โ requests did not appear to be reaching the backend at all.
Setup
On this server, Traefik sits in front of Drupal as a reverse proxy. Traefik watches the Docker socket and builds its routing configuration dynamically from container labels โ the so-called Docker provider mode.
[Internet] โ [Traefik :443] โ [Drupal :30080] โ [MariaDB]
(healthy) (healthy)
Both the Drupal and MariaDB containers were running and reported healthy. So the application was alive, yet the Traefik layer in front could not forward requests to it.
Investigation
The Traefik logs showed the following error repeating, on its communication with the Docker API:
Error response from daemon: client version 1.24 is too old.
Minimum supported API version is 1.40, please upgrade your client to a newer version
This appears to be the Docker daemon rejecting the connecting client (here, Traefik's built-in Docker client) because its API version is too old. Traefik was trying to connect with API version 1.24, while the daemon had raised its minimum supported version to 1.40, so the two no longer matched.
Traefik running in Docker provider mode fetches container information from the Docker API at startup and on each event to build its routing table. When that API connection is refused, it cannot load the routing configuration at all, and as a result it cannot dispatch to any of the services behind it. Drupal was not down โ there was simply no route to it.
Root cause
Checking the server's history, apt-get -y upgrade had been run on 2026-04-30, and in the process Docker CE was upgraded across a major version boundary (from what we could tell, from 26.1.2 to 29.4.1).
The newer Docker Engine had raised the minimum supported API version and now refuses connections from clients below it. Meanwhile, the running Traefik (v3.2, built in early 2025) had a built-in Docker client that still connected with API version 1.24.
When the Docker service was restarted as part of the Docker Engine upgrade, the Traefik container was restarted too. At that point Traefik tried to connect to the new daemon, was refused, and ended up unable to load its routing configuration. That seems to be the chain of events.
In summary, three things lined up to cause this outage:
apt-get upgradeupdated Docker CE (from a third-party repository) all the way across a major version.- The newer Docker Engine raised its minimum supported API version and began rejecting older clients.
- The running Traefik was still connecting with an old API version, so compatibility was lost once the daemon was updated.
Recovery
We changed the Traefik image from the minor-pinned traefik:v3.2 to traefik:v3, which tracks the latest in the v3 series, and restarted it โ on the expectation that a newer Traefik would ship a Docker client that speaks a newer API version.
# docker-compose.yml (the change)
services:
traefik:
- image: traefik:v3.2
+ image: traefik:v3
cd /home/ubuntu/traefik
docker compose pull
docker compose up -d
After the restart, Traefik could talk to the Docker API again, and routing to Drupal was restored. No changes were made to Drupal or MariaDB.
Preventing a recurrence
This outage was not about the reverse proxy alone โ it was a chain of "an OS-wide package update," "a major upgrade of the container platform (Docker Engine)," and "a client (Traefik) that had not kept up with it." With that in mind, here are the options we are currently considering.
Pin the Docker Engine version
Docker CE is provided from a third-party repository (download.docker.com), so running apt-get upgrade updates it across major versions too. To avoid an unintended major upgrade, one option is to hold the packages so they are excluded from upgrades.
sudo apt-mark hold docker-ce docker-ce-cli containerd.io
Held packages then have to be unheld deliberately when you want to update them.
Track the latest of the Traefik v3 series
Pinning a minor version (traefik:v3.2) means you cannot follow compatibility changes on the Docker API side, and you can get left behind as happened here. Referencing the latest of a major series, like traefik:v3, makes you less likely to hit Docker API compatibility problems. As of writing (2026-06), the latest Traefik major is the v3 series (v4 has not been released), and the latest stable appears to be the v3.7 series. Under Traefik's support policy, only the latest minor is actively supported, and a previous minor is treated as EOL once a newer minor ships โ so continuing to pin a specific minor tends to leave you behind on both support and compatibility, which is another reason to track the latest of the series. On the other hand, it trades that off against the risk of picking up unexpected behavior changes within the major series, so it is safer to operate it alongside verification on each update.
Reconsider bulk upgrades
Updating all packages โ including third-party ones โ in one go with apt-get upgrade carries the risk of pulling in a major version of the container platform, as it did here. Narrowing the operation to security updates (for example, configuring unattended-upgrades to auto-apply only security updates) makes it easier to avoid unintended major upgrades.
Summary
Even when the application is up, if the reverse proxy in front of it can no longer connect to the container platform's API, the whole site becomes unreachable. Here the trigger was a major upgrade of the Docker Engine, and the cause was that the running Traefik had been left behind on an old API version. Leaving the container platform in the path of a bulk apt-get upgrade means the same kind of compatibility problem can surface on the next restart, so we plan to pin versions and revisit how updates are applied.



Comments
โฆ