NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Go modules · #1974 by repository stars
Last release today
07 Oct 2026
Release timing varies
gaps range from 9 days to 2 months
Nearly every release is documented
notes for 55 of 56 stable releases
Nothing withdrawn
no release was ever pulled
9 years old
170 releases · first in 2018
Nothing published for this version
Load Balancers with Primary IPs
Load Balancers can now be created with existing Primary IPs instead of system managed public IPs. Because the Primary IPs exist on their own, a Load Balancer's public addresses can survive deleting and recreating the Service, so you don't have to change DNS records. Set the new Service annotations load-balancer.hetzner.cloud/public-net-ipv4 and load-balancer.hetzner.cloud/public-net-ipv6 to the ID of a Primary IP:
metadata:
annotations:
load-balancer.hetzner.cloud/public-net-ipv4: "4711"
load-balancer.hetzner.cloud/public-net-ipv6: "4712"See the Primary IPs guide for details.
One column per quarter.
Nothing published for this version
Features support Kubernetes v1.37 ( f188865 ) Bug Fixes drop Kubernetes v1.33 support
Nothing published for this version
We derive the IPv6 ExternalIP of a Node from the IPv6 subnet the server reports, by using the first address of that subnet. This is wrong for servers
We derive the IPv6 ExternalIP of a Node from the IPv6 subnet the server reports, by using the first address of that subnet. This is wrong for servers that use a different address out of their subnet, and Robot does not report a subnet for every server, in which case the Node got no IPv6 ExternalIP at all. You can now set the address explicitly through the Node annotation instance.hetzner.cloud/external-ipv6:
kubectl annotate node $NODE_NAME --overwrite \
instance.hetzner.cloud/external-ipv6=2001:db8:1234::5The annotation works for Cloud and Robot servers and takes precedence over the derived address. It requires IPv6 to be enabled for Node addresses via HCLOUD_INSTANCES_ADDRESS_FAMILY.
Nothing published for this version
instances : configure the IPv6 ExternalIP through a Node annotation
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
load-balancer : warn on deprecated Load Balancer Type
The datacenter property was removed from the Server object (see changelog . For backwards compatibility, we statically compute the datacenter from the
The datacenter property was removed from the Server object (see changelog. For backwards compatibility, we statically compute the datacenter from the location to fill the topology.kubernetes.io/zone and failure-domain.beta.kubernetes.io/zone labels. In the next major release we will stop setting these values. To stop setting these values now, you can set the environment variable HCLOUD_INSTANCES_ZONE_LABEL_ENABLED=false. See here for more details.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
chart : expose podSecurityContext and securityContext values
Nothing published for this version
Renamed HCLOUD_SERVER_CACHE_TTL to HCLOUD_SERVER_CACHE_MAX_AGE . The server cache lifetime is now configured via HCLOUD_SERVER_CACHE_MAX_AGE (default
Renamed HCLOUD_SERVER_CACHE_TTL to HCLOUD_SERVER_CACHE_MAX_AGE. The server cache lifetime is now configured via HCLOUD_SERVER_CACHE_MAX_AGE (default 10s). Individual controllers may override this default for specific lookups — for example, the routes controller uses a longer max age. Action required: if you set HCLOUD_SERVER_CACHE_TTL, switch to HCLOUD_SERVER_CACHE_MAX_AGE; the old variable is no longer recognized.
Removed the hcops/AllServersCache.* operation metrics. The legacy AllServersCache was replaced by the shared server cache, so the following cloud_controller_manager_operations_total series labeled op="hcops/AllServersCache.*" are no longer emitted:
hcops/AllServersCache.ByIDhcops/AllServersCache.ByNamehcops/AllServersCache.ByPrivateIPhcops/AllServersCache.getCachehcops/AllServersCache.refreshCacheThey are superseded by the new server cache metric cloud_controller_manager_server_cache_requests_total, a counter partitioned by subsystem, mode, and result:
cloud_controller_manager_server_cache_requests_total{subsystem="instances_v2", mode="all", result="hit"}
cloud_controller_manager_server_cache_requests_total{subsystem="routes", mode="all", result="miss"}
Update any dashboards or alerts referencing the old op series accordingly.
Nothing published for this version
This release introduces an experimental server cache to reduce Hetzner Cloud API calls. During an experimental phase, breaking changes on those featur…
This release introduces an experimental server cache to reduce Hetzner Cloud API calls. During an experimental phase, breaking changes on those features may occur within minor releases.
The node and node lifecycle controllers look up Servers by ID or name, generating significant API traffic during cluster scaling. A new cache sits between the controllers and the API to serve these lookups, reducing the number of requests.
It is enabled by default since we believe the implementation is safe in practice, but is experimental and may see breaking changes within minor releases. Configure it via environment variables:
HCLOUD_SERVER_CACHE_MODE (all | one | off, default all):
all — fetch all Servers once and serve lookups from the snapshot until the TTL expires.one — cache each Server individually with its own expiration.off — disable caching; every lookup hits the API.HCLOUD_SERVER_CACHE_TTL (duration, default 10s): lifetime of cached entries (e.g. 30s, 2m); values above a minute are not recommended.
Nothing published for this version
routes controller on node name drift
Nothing published for this version
robot : allow Robot support without API credentials for IP-based LB targets
Nothing published for this version
To avoid a breaking change in HCCM, we decided to statically map from the old location names to the existing datacenter names for the topology.kuberne…
The server.datacenter field is deprecated and will be removed from the API response after July 2026: https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters
To avoid a breaking change in HCCM, we decided to statically map from the old location names to the existing datacenter names for the topology.kubernetes.io/zone label. For new locations we will return the location name without a -dcxx suffix.
Deployments of hcloud-cloud-controller-manager that are not updated when the field is removed from the API will panic with the following error:
"Observed a panic" panic="runtime error: invalid memory address or nil pointer dereference" panicGoValue=""invalid memory address or nil pointer dereference""
We have published an RFC which details how we want to continue utilizing the labels topology.kubernetes.io/zone and topology.kubernetes.io/region: #1146 (comment)
Nothing published for this version
drop support for Kubernetes v1.31
Nothing published for this version
tcp service created for service with unsupported load balancer protocol
respect proxy protocol default from config for load balancer status
Nothing published for this version
Previously, route reconciliation is performed at a fixed interval of 30s. This leads to unnecessary API requests, as a GET /v1/networks/{id} call is t
Previously, route reconciliation is performed at a fixed interval of 30s. This leads to unnecessary API requests, as a GET /v1/networks/{id} call is triggered every 30s, even when no changes have occurred.
Upstream, we have contributed an event-driven approach, similar to the mechanisms used by other controllers such as the Load Balancer controller. With this new approach, route reconciliation is triggered by node additions, node deletions, or changes to a node’s PodCIDRs or Addresses. Additionally, to ensure consistency, reconciliation still occurs periodically at a randomized interval between 12 and 24 hours.
This feature is now enabled by default.
If you encounter any problems you can disable the feature by setting the following Helm value:
args.feature-gates=CloudControllerManagerWatchBasedRoutesReconciliation=false
Configure cluster-wide defaults for Load Balancers via the extended HCLOUD_LOAD_BALANCERS_* env vars. These values automatically apply during Load Balancer creation and reconciliation whenever annotations are omitted. Learn more about it in the reference documentation
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
We have introduced a custom ClusterRole for the HCCM component, based on the upstream recommendation from sig-cloud-provider.
We have introduced a custom ClusterRole for the HCCM component, based on the upstream recommendation from sig-cloud-provider.
To ensure a smooth transition, we renamed the ClusterRoleBinding by adding the :restricted suffix. This change was necessary because the roleRef field in a ClusterRoleBinding is immutable, which would otherwise cause errors during a Helm upgrade.
As a result, users who deploy HCCM using the provided Kubernetes manifests must manually delete the old ClusterRoleBinding after applying the updated manifests. Users deploying via the Helm chart do not need to take any action.
kubectl delete clusterrolebindings.rbac.authorization.k8s.io system:hcloud-cloud-controller-manager
We have introduced a custom ClusterRole for the HCCM component, based on the upstream recommendation from sig-cloud-provider.
We have introduced a custom ClusterRole for the HCCM component, based on the upstream recommendation from sig-cloud-provider.
Due to this change, users who deploy HCCM using the provided Kubernetes manifests must manually remove the old ClusterRoleBinding after applying the updated manifests. Users deploying via the Helm chart do not need to perform any migration steps.
kubectl delete clusterrolebindings.rbac.authorization.k8s.io system:hcloud-cloud-controller-manager
We have introduced a custom ClusterRole for the HCCM component, based on the upstream recommendation from sig-cloud-provider.
We have introduced a custom ClusterRole for the HCCM component, based on the upstream recommendation from sig-cloud-provider.
Because of this change, a simple helm upgrade may fail due to immutable fields in the existing ClusterRoleBinding. To ensure a successful upgrade, you must delete the existing ClusterRoleBinding before upgrading. This will make HCCM temporarily unavailable until the new version is deployed. Please avoid making any changes to the clusters, especially node- or service-related modifications, during this time.
kubectl delete clusterrolebindings.rbac.authorization.k8s.io system:hcloud-cloud-controller-manager
Nothing published for this version
If your CCM is configured for a Private Network, Load Balancers can now join one of its subnets. To place a Load Balancer in a specific subnet, use th
If your CCM is configured for a Private Network, Load Balancers can now join one of its subnets. To place a Load Balancer in a specific subnet, use the new load-balancer.hetzner.cloud/private-subnet-ip-range annotation. Learn more about this feature here.
Currently, route reconciliation is performed at a fixed interval of 30s. This leads to unnecessary API requests, as a GET /v1/networks/{id} call is triggered every 30s, even when no changes have occurred.
Upstream we have proposed an event-driven approach, similar to the mechanism used by other controllers such as the Load Balancer Controller. With this new approach, route reconciliation is triggered on node additions, node deletions, or when the PodCIDRs or Addresses of nodes change. Additionally, to ensure consistency, reconciliation will still occur periodically at a randomized interval between 12 and 24 hours.
We are close to merging a Kubernetes Enhancement Proposal (KEP). Furthermore, a pull request containing the implementation is already open in the Kubernetes repository.
In this release, we replaced the upstream controller-manager and cloud-provider libraries with our own forks. These forks are based on the upstream v0.34.1 release (aligned with Kubernetes v1.34.1) and include our patches on top.
This feature is disabled by default and will not affect existing deployments unless explicitly enabled. We recommend testing it in a non-production environment before considering use in production.
As the KEP has not yet been reviewed for production readiness, the feature gate name may change in an upcoming release. Since this feature is marked as experimental, such changes will not be considered breaking.
To enable the feature, set the following Helm value:
args.feature-gates=CloudControllerManagerWatchBasedRoutesReconciliation=true
Nothing published for this version
This release introduces an experimental feature to address #395.
This release introduces an experimental feature to address #395.
Currently, route reconciliation is performed at a fixed interval of 30s. This leads to unnecessary API requests, as a GET /v1/networks/{id} call is triggered every 30s, even when no changes have occurred.
Upstream we have proposed an event-driven approach, similar to the mechanism used by other controllers such as the Load Balancer Controller. With this new approach, route reconciliation is triggered on node additions, node deletions, or when the PodCIDRs or Addresses of nodes change. Additionally, to ensure consistency, reconciliation will still occur periodically at a randomized interval between 12 and 24 hours.
We are close to merging a Kubernetes Enhancement Proposal (KEP). Furthermore, a work-in-progress pull request containing the implementation is already open in the Kubernetes repository.
In this release, we replaced the upstream controller-manager and cloud-provider libraries with our own forks. These forks are based on the upstream v0.33.2 release (aligned with Kubernetes v1.33.2) and include our patches on top.
This feature is disabled by default and will not impact existing deployments unless explicitly enabled. We do not recommend running this feature in production environments at this stage. However, we welcome early testers who can try it in non-critical setups. Running with this feature active is enough for us to analyze its impact. No additional feedback is required.
To enable the feature, set the following Helm value:
args.feature-gates=CloudControllerManagerWatchBasedRoutesReconciliation=true
This release introduces an experimental feature to address #395.
This release introduces an experimental feature to address #395.
Currently, route reconciliation is performed at a fixed interval of 30 seconds. This leads to unnecessary API requests, as a GET /v1/networks/{id} call is triggered every 30 seconds, even when no changes have occurred.
Upstream we have proposed an event-driven approach, similar to the mechanism used by other controllers such as the Load Balancer Controller. With this new approach, route reconciliation is triggered on node additions, node deletions, or when the PodCIDRs or Addresses of nodes change. Additionally, to ensure consistency, reconciliation will still occur periodically at a randomized interval between 12 and 24 hours.
We are close to merging a Kubernetes Enhancement Proposal (KEP). Furthermore, a work-in-progress pull request containing the implementation is already open in the Kubernetes repository.
In this release, we replaced the upstream controller-manager and cloud-provider libraries with our own forks. These forks are based on the upstream v0.33.2 release (aligned with Kubernetes v1.33.2) and include our patches on top.
This feature is disabled by default and will not impact existing deployments unless explicitly enabled. We do not recommend running this feature in production environments at this stage. However, we welcome early testers who can try it in non-critical setups. Running with this feature active is enough for us to analyze its impact. No additional feedback is required.
To enable the feature, set the following Helm value:
args.feature-gates=CloudControllerManagerWatchBasedRoutesReconciliation=true
add Kubernetes v1.33 and remove EOL version v1.29
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
binaries are missing in the release
binaries are missing in the release
Your coding agent can read these notes before it upgrades. Set up the MCP server →