On June 15, 2026, Hetzner repriced its entire cloud lineup — an average increase of 99% in Germany and 158% in the US according to heise's analysis, with a CX23 going from €3.99 to €5.49 and a CCX13 nearly tripling from €15.99 to €42.99. Every team running a fleet there is now auditing line items. And there is one line that survived the repricing untouched, appears once per server, and can be deleted outright: the primary IPv4 address, billed at €0.50 per month per instance, while every server's IPv6 /64 ships free.
Provision your worker nodes IPv6-only — Hetzner's order flow and API support it directly — and a 50-node fleet saves €25/month, €300/year. Let's be honest immediately: that is the smallest lever on a post-repricing Hetzner bill, and pulling it buys you a real problem, because github.com and ghcr.io still publish no AAAA records, which means git clones and image pulls fail on an IPv6-only node before your workloads even start. This post does the savings math node by node, shows exactly what breaks first, walks the four ways to bridge the gap, and lists where a Cluster API Provider Hetzner (CAPH) fleet needs explicit IPv6-only configuration versus what just works.
The Savings Math, Node by Node
The arithmetic is trivial; the judgment is not. Per the June 15, 2026 adjustment, instance prices are listed excluding IPv4, and the primary IPv4 costs €0.50/month (billed hourly, attached or not). IPv6 is free. So for worker fleets:
| Worker nodes | Monthly savings | Annual savings |
|---|---|---|
| 10 | €5.00 | €60 |
| 25 | €12.50 | €150 |
| 50 | €25.00 | €300 |
Whether that matters depends entirely on what your nodes cost — and this is where the sensitivity is worth spelling out, because the June repricing moved the ratio dramatically depending on family:
| Node type (Germany) | New monthly price | IPv4 as share of node cost |
|---|---|---|
| CX23 (shared Intel) | €5.49 | ~9.1% |
| CAX11 (shared Arm) | €5.99 | ~8.3% |
| CPX22 (shared AMD) | €19.49 | ~2.6% |
| CCX13 (dedicated) | €42.99 | ~1.2% |
The pattern: the cheaper your nodes, the more the IPv4 line item matters proportionally. A fleet of small CAX Arm workers — a common shape for buildpack builds and horizontal web scaling — is quietly paying an 8–9% surcharge for public IPv4 addresses that, on a worker node behind a load balancer, mostly sit unused. A CCX fleet can ignore the whole question.
There are also three non-euro reasons teams do this, and they are arguably stronger than the €300:
- Attack surface. A worker with no public IPv4 stops appearing in mass IPv4 scans. (It's still reachable over IPv6 if you expose it, but the background-noise scanning economy remains overwhelmingly IPv4.)
- Egress discipline. When workers can't casually reach the IPv4 internet, every external dependency has to pass through a gateway you configured — which means you finally know what your cluster talks to.
- Address scarcity is directional. Hetzner froze the IPv4 price in this round, but IPv4 exhaustion economics only point one way. The teams that decouple now reprice later on their own schedule.
What Breaks First: The IPv4-Only Internet You Still Depend On
Here is the part that stops most teams, and it breaks before your workloads do — during node provisioning, when cloud-init and the kubelet try to fetch packages and images.
The single worst offender is GitHub. As of 2026, github.com, api.github.com, and ghcr.io publish no AAAA records — the community-run tracker doesgithubhaveipv6yet.com still answers "no," and GitHub has no published IPv6 roadmap or ETA. On an IPv6-only node, that means:
git clone https://github.com/...fails with no route to host- Release-asset downloads (
curlto github.com / codeload) fail - Image pulls from ghcr.io fail — and a large share of the cloud-native ecosystem now publishes primarily to ghcr.io
What does work over IPv6 is almost everything fronted by a modern CDN: GitHub Pages (served via a CDN, ironically), GitLab.com, Cloudflare-fronted endpoints, most distro package mirrors, and Docker Hub. The failure mode is therefore patchy rather than total — which makes it worse, because a cluster appears healthy right up until a deployment references ghcr.io/some/image and the pull hangs. If your platform's provisioning path pulls anything from GitHub — kubeadm binaries from release assets, a CNI manifest, an operator image on ghcr — an IPv6-only node will fail to join the cluster at all.
So the €0.50 question becomes: what's the cheapest reliable bridge to the IPv4-only remnant of the internet?
Four Ways to Bridge, From Zero-Ops to Owned
1. Public NAT64/DNS64 — zero infrastructure, zero guarantees. Free public resolvers such as Kasper Dupont's nat64.net will synthesize AAAA records for IPv4-only hosts and translate your traffic. Setup is one resolver line in systemd-resolved. But read the terms: the operator promises no availability, may keep logs, and offers no compensation for downtime. A third party now sits in the path of your git clones and image pulls. Fine for a homelab or a proof of concept; not a dependency a production fleet should ship with.
2. Run your own NAT64 with Jool. Jool is the widely deployed open-source NAT64 kernel module for Linux. The shape: one small dual-stack instance runs Jool as a stateful translator under the well-known prefix 64:ff9b::/96, and a DNS64-capable resolver (BIND, or CoreDNS forwarding to a DNS64 upstream) synthesizes AAAA records pointing into that prefix. Your fleet's route for 64:ff9b::/96 goes to the Jool box. Cost: one CX23 (€5.49 + €0.50 for its own IPv4) and a kernel module to operate. Break-even against the savings arrives around a dozen nodes.
3. The Hetzner-native NAT gateway — usually the right answer. Hetzner cloud private networks are free, RFC1918 IPv4, and independent of public addressing. So the classic pattern applies: give worker nodes no public IPv4, attach everything to the private network, and route IPv4 egress through one dual-stack gateway node doing plain masquerade. One €0.50 public IPv4 serves the whole fleet instead of N of them; GitHub and ghcr.io work unmodified because egress genuinely is IPv4; no NAT64 translation layer, no DNS64, no exotic failure modes. The trade: the gateway is a single point of egress failure, so it needs the same care as any other piece of shared infrastructure (or a failover pair).
4. Registry pull-through cache — fix the biggest breakage class at the source. Run a mirror/pull-through cache (Harbor, Zot, or registry:2 in proxy mode) on one dual-stack node and point containerd's registry config at it. Image pulls — the breakage that hurts a Kubernetes fleet most — never leave the private network again, and you gain locality and rate-limit insulation as side effects. Pair it with option 2 or 3 to cover git and release downloads.
Which one, at which size? Under ~10 nodes: don't bother going IPv6-only at all, or use the NAT gateway if you already run one. 10–50 nodes: NAT gateway plus a pull-through cache is the boring, debuggable combination — you were likely halfway there anyway. Choose Jool/NAT64 when you want native-feeling IPv6-only (no RFC1918 anywhere) or you're standardizing on IPv6-only as a matter of architecture rather than cost.
Where CAPH, kubelet, and the CNI Need Explicit Config
If the fleet is managed by Cluster API with the Hetzner provider, IPv6-only is a declared property of the machine template — but several things must be set explicitly.
The machine template. HCloudMachineTemplate exposes the public network toggles directly:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: HCloudMachineTemplate
spec:
template:
spec:
publicNetwork:
enableIPv4: false
enableIPv6: trueTwo rules attach to this. First, if you disable both public IPs, CAPH requires the private network to be enabled — the node has to be reachable somehow. Second, pin a recent CAPH release: issue #312 documented publicNetwork settings from the template being applied incorrectly, exactly the kind of bug that turns a planned IPv6-only rollout into surprise dual-stack billing. Changing the template triggers a rolling MachineDeployment replacement, so the migration is per-node and reversible.
kubelet. The kubelet must advertise the address other nodes can actually reach: pass --node-ip with the IPv6 address (or the private IPv4 if you went the NAT-gateway route with private-net-only nodes). Leave it unset and the kubelet's autodetection can pick an address that isn't routable from the rest of the cluster, which surfaces as kubectl logs/exec timeouts — the API server can't reach the kubelet — rather than an obvious join failure.
The CNI. This is a cluster-level decision, not per-node: pod and service CIDRs are set at cluster creation and are effectively immutable. For Cilium, IPv6 pod networking means ipv6.enabled: true plus an IPv6 pod pool (clusterPoolIPv6PodCIDRList alongside — or instead of — the IPv4 one), and the Cluster API cluster spec needs matching IPv6 (or dual-stack) pods.cidrBlocks and services.cidrBlocks. The pragmatic consequence: if your existing cluster is IPv4-single-stack on the private network, IPv6-only nodes with IPv4 pod networking over the private net is the low-risk move — you drop the public IPv4 line item without touching pod CIDRs. Full IPv6-only pod networking is a new-cluster decision.
Ingress and DNS. End users notice nothing: the Hetzner Load Balancer at the edge stays dual-stack, terminating IPv4 for the 30-something percent of the internet that still needs it, and forwards to workers over the private network. If you chose the NAT64 route, cluster DNS (CoreDNS) must forward to your DNS64 resolver so pods get synthesized AAAA records; with the NAT-gateway pattern, DNS needs no changes.
The Decision Rule
Strip the analysis to a rule of thumb:
- Worth doing when you run 10+ small-instance workers (CX/CAX — where IPv4 is an 8–9% per-node surcharge), when you already operate a NAT gateway or egress proxy, or when you want the scan-surface and egress-discipline benefits and would build a gateway anyway.
- Not worth doing for a five-node fleet with no existing gateway: €2.50/month does not fund the first hour of debugging a NAT64 path, and the boring alternative (keep the IPv4s) costs less than a coffee.
- The external variable to watch is GitHub. The day github.com and ghcr.io publish AAAA records, the largest bridge requirement disappears and IPv6-only workers become close to free to operate. Until then, budget for the gateway.
The June repricing didn't make the €0.50 line item bigger — it made everything around it bigger, which perversely makes the IPv4 charge less significant in relative terms on premium nodes and more visible on cheap ones. Treat it accordingly: not as a cost-recovery move that offsets a doubled compute bill, but as the cheapest forcing function available for knowing exactly how your fleet touches the internet. That knowledge, unlike the €300, compounds.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, including a Cluster API-managed Hetzner fleet where node networking is a declared template property rather than a hand-configured snowflake. Star the repo on GitHub or deploy your first app today.



