Skip to content

v1.70.0 — the registries and channels we could not reach

Choose a tag to compare

@amayer1983 amayer1983 released this 02 Aug 17:34

The last of the findings from reading other projects' bug trackers. Three of these made a whole class of setup silently unusable while docker pull kept working — which is a confusing pair of facts to be handed.

Registries Docksentry could not reach at all

Plain HTTP. https:// was hardcoded in every registry URL, so a local or internal HTTP-only registry reported "unreachable / unauthorized" on every cycle and there was no setting to change it.

INSECURE_REGISTRIES=localhost:5000,*.internal

Only hosts named there. Never guessed, and never a fallback when TLS fails — a tool that quietly retries over plain HTTP is a tool that hands credentials to whoever answers. Docker's own client takes the same position.

Basic auth. The stock registry:2 behind htpasswd answers WWW-Authenticate: Basic, and the parser returned nothing for any non-Bearer challenge — so negotiation gave up and the credentials already sitting in your config.json were never sent.

These two land together because either alone still leaves that registry unreachable. Verified end to end against a real registry:2 with htpasswd over HTTP: digest fetched, tags listed.

ntfy on a protected topic

No Authorization header was ever sent, so a self-hosted ntfy with auth-default-access: deny, or any reserved topic on ntfy.sh, rejected every push with a single log line and nothing to reach for.

NTFY_TOKEN=tk_...
# or
NTFY_USER=me
NTFY_PASSWORD=...

Measured against a real protected server: 403 without, 200 with.

Discord dropped the notification entirely above 25 updates

Discord rejects an embed with more than 25 fields — with a 400, so the message was lost rather than truncated. Come back from a holiday to 30 pending updates and you got silence.

Split into messages of 25 now, numbered when there is more than one.

And 429 is no longer treated as terminal. It is the one status that is explicitly transient and carries Retry-After, and every channel was discarding the notification at exactly the moment the service was busiest — which is when "3 containers failed to update" matters most.

The cgroup version was cached once per process

It feeds the arguments used when recreating a container. On a mixed fleet, whichever host was asked first decided for all of them — and knobs like memory.swappiness are cgroup-v1-only, so getting it wrong either drops a setting the container had or emits one the daemon rejects.

Not hypothetical. Measured on a live two-host install: the local daemon reports cgroup 2, the Podman host reports 1. One of those answers was being applied to both.

Third time a per-process cache has turned out to be a multi-host trap here, so the key is explicit now rather than implied.

Upgrading is the usual docker pull ghcr.io/amayer1983/docksentry:latest, or nothing at all with auto-selfupdate on.