Skip to main content

Hetzner Pulled openSUSE 15 and Deprecated Debian 11: Rebuild Your CAPH Node Images Before November 30

10 min readDora NodaDora Noda
Share
On this page

Two Hetzner distro images died in four months. opensuse-15 stopped being available for new servers on July 30, 2026, and debian-11 — deprecated August 31 — follows it off the orderable list after November 30. If your Cluster API fleet's machine templates still reference either image, you have about ten weeks before scale-up starts failing at server-order time: not a bad deploy, not a failing rollout, but a machine that never gets created at all.

Running servers are unaffected — Hetzner is not deleting anything already booted. The breakage is narrower and sneakier: anything that creates a new server from a dead image name fails. That means cluster-autoscaler scale-outs, MachineDeployment rollouts, control-plane replacements, and — the one people forget — your own Packer pipeline if it still builds node images from the dead base. This post gives you the dated timeline, the audit commands, a replacement-base comparison, and a numbered rebuild-and-roll runbook.

What died, what's dying, and when

All dates below come from the Hetzner Cloud changelog, which is the authoritative source here, not this post. The upstream end-of-life dates explain why Hetzner is pulling the images now.

ImageHetzner image IDs (x86 / arm)DeprecatedUnavailable for new serversUpstream status
opensuse-15204457491 / 204457492Apr 30, 2026Jul 30, 2026 (already dead)Leap 15.6 EOL end of 2025; successor is Leap 16
debian-1145557056 / 103907373Aug 31, 2026After Nov 30, 2026Bullseye LTS ended Aug 31, 2026

Two details are worth pausing on. First, Hetzner deprecated debian-11 on the exact day Debian's own LTS support for Bullseye ended — August 31, 2026, five years after Bullseye's August 2021 release. Regular security support had already ended back in August 2024, so the box you are still booting had volunteer-LTS-only coverage for two years and now has none outside paid Extended LTS.

Second, opensuse-15 was already seven months past upstream end-of-life when Hetzner pulled it. These removals are not Hetzner being aggressive. They are Hetzner refusing to let new servers boot onto distros nobody patches.

The replacement runway is also already partly consumed. Debian 12 (Bookworm) left standard support on July 11, 2026 and is on LTS until June 30, 2028; Debian 13 (Trixie) is the current stable. So "just move to Debian 12" buys you under two years of support, while jumping to 13 buys a full cycle — a tradeoff the comparison table below makes explicit.

Why this breaks CAPH fleets at the worst moment

A Cluster API Provider Hetzner (CAPH) fleet references its node OS in HCloudMachineTemplate, at spec.template.spec.imageName. That field usually points at a snapshot you built with Packer — and snapshots you already own keep working. The failure mode hits in two places:

  1. Templates pointing at stock image names. If any template still says imageName: debian-11 or imageName: opensuse-15, every new Machine from it issues a create-server call against an image Hetzner will not sell you. The Machine sits in provisioning forever. Your first symptom is the cluster-autoscaler failing to scale out during a traffic spike, or a routine MachineDeployment rollout stalling with new replicas that never appear.
  2. Packer pipelines building from the dead base. If your hcloud Packer builder uses "image": "debian-11" as its source, your node-image factory breaks the day the image goes unavailable — exactly when you need it most to build the replacement. Audit the builder source image, not just the templates.

There is a deprecation-window wrinkle, too. Hetzner treats deprecated images as opt-in: creating a server from one requires explicitly allowing deprecated images (the Ansible module even names the flag allow_deprecated_image, defaulting to no). So between deprecation and removal, automation that does not pass the opt-in fails early — which is arguably a favor, since it surfaces the problem before November 30 instead of after.

Run the audit now. It takes two minutes:

bash
# Every CAPH template in the management cluster and what image it pins
kubectl get hcloudmachinetemplates -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{" -> "}{.spec.template.spec.imageName}{"\n"}{end}'
 
# What Hetzner thinks of those images (deprecation field; null means healthy)
hcloud image describe debian-11 -o json | jq '{name: .name, deprecated: .deprecated, deprecation: .deprecation}'
hcloud image list --type system

Note the API detail in that second command: Hetzner replaced the old boolean-ish deprecated response field with a richer deprecation object describing if, when, and how a resource is deprecated, and the old field is removed on November 2, 2026. If you have scripts parsing the old field, they break four weeks before the Debian 11 deadline — fix them in the same pass.

Also grep your Packer and image-builder sources for the dead names. A template pointing at a healthy snapshot means nothing if the pipeline that refreshes that snapshot boots from debian-11.

Pick your replacement base

You have four realistic options. There is no universally right answer, but there is a wrong one: staying put.

BaseSupport windowBest forWatch out for
Debian 12 (Bookworm)LTS until Jun 30, 2028Smallest diff from Debian 11; fastest migrationUnder 2 years of support left; you will do this again in 2028
Debian 13 (Trixie)Full stable cycle (into 2028+, then LTS)Greenfield rebuilds; longest runwayRequires merged-/usr; biggest behavior delta to validate
Ubuntu 24.04 LTSStandard support to 2029, ESM to 2034Teams already standardized on Ubuntu toolingDifferent cloud-init/network defaults to re-validate; snap debates aside, it is not your current base
Talos snapshotRolling releases, API-driven upgradesImmutable, minimal, Kubernetes-only nodes; no SSH/cloud-init driftRequires the Talos bootstrap and control-plane providers (CABPT/CACPPT) plus CAPH's hcloud-talos flavor — a bigger architectural move

For most Debian-11-based CAPH fleets, Debian 12 is the pragmatic November-30 fix and Talos is the strategic one. The Debian 12 path keeps your kubeadm bootstrap, cloud-init user data, and existing Packer pipeline, changing only the base. The Talos path deletes entire failure classes — no package drift, no SSH, configuration via gRPC — but it is a re-platforming, not a rebase, and ten weeks is tight if you have never run it. A reasonable split: rebase to Debian 12 (or 13) now to clear the deadline, and evaluate Talos on a non-production workload cluster on its own schedule.

One input to that evaluation: Debian 12 itself is already on LTS, so a Debian 12 rebase today schedules your next forced migration for mid-2028. If your fleet is large enough that node-image migrations are multi-week projects, that argues for Debian 13 now despite the bigger validation bill.

The rebuild-and-roll runbook

This is the concrete artifact the title promised. It assumes the standard production CAPH flow: Packer-built snapshots referenced by HCloudMachineTemplate, rolled out by pointing MachineDeployments (and the KubeadmControlPlane) at a new template. Adjust names to taste.

Step 1 — Build the new snapshot. Update the Packer hcloud builder to the new base image and bake Kubernetes, the container runtime, and the CNI binaries in, as before. Label the snapshot so CAPH's image lookup resolves it:

json
{
  "builders": [{
    "type": "hcloud",
    "image": "debian-12",
    "server_name": "caph-node-base",
    "snapshot_name": "caph-debian12-k8s-1-36",
    "snapshot_labels": { "caph-image-name": "caph-debian12-k8s-1-36" }
  }]
}

Verify the snapshot exists and is resolvable before touching any template. A typo here is the cheapest failure in this runbook; catch it now.

Step 2 — Create a new HCloudMachineTemplate. Never edit the old template in place — Cluster API templates are effectively immutable, and a new object gives you a clean rollback target:

yaml
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: HCloudMachineTemplate
metadata:
  name: workers-debian12-k8s-1-36
spec:
  template:
    spec:
      imageName: caph-debian12-k8s-1-36
      # ... server type, networks, placement groups unchanged

Step 3 — Re-validate the new base before it carries load. This is the step teams skip and then debug at 2 a.m. Boot one canary node from the new template and check, at minimum:

  • CNI datapath vs. the new kernel. eBPF-based CNIs have kernel floors, and iptables-mode components care about the nftables backend. Confirm your CNI version supports the new base's kernel (5.10 to 6.1+ is a real jump) and that pod-to-pod traffic actually flows on the canary.
  • kubelet and runtime. Confirm the kubelet's cgroup driver, the containerd config, and any version skew against the control plane. Rebuilt images are also how kubelet patch versions quietly drift — pin them.
  • cloud-init rendered output. Diff the actual rendered network config on the canary against a current node, not just the user-data source. Hetzner-datasource behavior and cloud-init version defaults both move between bases.
  • TLS clients inside the cluster. Debian 12 ships OpenSSL 3.0 (up from 1.1.1). Anything doing TLS with legacy parameters — old webhooks, pinned ancient clients — needs a handshake test, not an assumption.
  • Language runtimes. Python 3.9 to 3.11 (or 3.13 on Trixie) breaks unpinned scripts and vendored wheels. Grep the image build for version assumptions.

Step 4 — Roll the fleet. Point the MachineDeployment (and, separately and first in lower environments, the KubeadmControlPlane) at the new template and let the rolling upgrade replace nodes. Watch machine-creation errors specifically — this is the moment a bad imageName announces itself — and keep the old template around until every pool is green.

Step 5 — Retire and record. Delete the old templates, snapshot a list of what each pool now runs on, and write down the new base's own EOL date somewhere your future self will see it. Which brings us to the policy.

The standing policy so the next removal is a calendar event

Distro-image churn is not a one-off; it is the job. Hetzner publishes exactly the signals you need — the gap is that nobody subscribes to them. Adopt these four, in order of effort:

  1. Subscribe to the changelog RSS feed (docs.hetzner.cloud/changelog/feed.rss) in whatever you actually read — feed reader, Slack RSS integration, or a small poller that opens a ticket on entries tagged Servers/Images. Both removals in this post were announced there months before they bit.
  2. Poll the deprecation field programmatically. A nightly job that lists system images and alerts on non-null deprecation turns "surprise" into "ticket filed the morning it was announced." Remember the old deprecated field dies November 2, 2026 — query the new one.
  3. Audit pinned images quarterly. Re-run the two audit commands from this post on a schedule. Fifteen minutes, four times a year, catches the template someone hand-edited back to a stock image name.
  4. Rebuild node images on a cadence, not on panic. A monthly or quarterly Packer refresh against current bases means your pipeline is always warm and your snapshots are never a year stale when a removal lands. The teams hurt by the Debian 11 deadline are the teams whose last successful image build predates the deprecation notice.

The meta-lesson is the TODO item's own phrasing: track the image changelog the way you track the Kubernetes changelog. You would never let a Kubernetes minor version go end-of-life as a surprise; give your node OS the same calendar discipline.

Owning the machines means owning the base image

Every image removal is a small reminder of what self-hosting actually means. On a managed platform, someone else rebuilds the node image, re-validates the CNI, and rolls the pool while you sleep. On machines you own — whether bare Hetzner Cloud servers or a CAPH-reconciled fleet — the base image is your dependency, with your EOL dates and your rollout. That is the price of the control, and most months the price is zero. November 30 is one of the months it comes due.

The good news is that the fix is entirely mechanical: audit today, rebase this month, roll next month, and install the four-item policy so the next removal arrives as a scheduled migration. Ten weeks is plenty — if you start before the deadline does your planning for you.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Node-image lifecycles, fleet rollouts, and the changelog-watching are our problem so they don't have to be yours. Star the repo on GitHub or deploy your first app today.

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex