This solver can be used when you want to use cert-manager with the Hetzner Cloud DNS API.
Fork of vadimkim/cert-manager-webhook-hetzner, rewritten for the Hetzner Cloud API (api.hetzner.cloud). Hetzner migrated DNS management from dns.hetzner.com to api.hetzner.cloud in November 2025, and the upstream webhook does not support the new API.
- go >= 1.24.0
- helm >= v3.0.0
- kubernetes >= v1.22.0
- cert-manager >= 0.12.0
Follow the instructions using the cert-manager documentation to install it within your cluster.
helm repo add cert-manager-webhook-hetzner https://sshine.github.io/cert-manager-webhook-hetzner
helm install --namespace cert-manager cert-manager-webhook-hetzner cert-manager-webhook-hetzner/cert-manager-webhook-hetznerhelm install --namespace cert-manager cert-manager-webhook-hetzner deploy/cert-manager-webhook-hetznerNote: The kubernetes resources used to install the Webhook should be deployed within the same namespace as the cert-manager.
To uninstall the webhook run
helm uninstall --namespace cert-manager cert-manager-webhook-hetznerCreate a ClusterIssuer or Issuer resource as following:
(Keep in mind that the example uses the Staging URL from Let's Encrypt. See Getting Started for the production URL.)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: mail@example.com
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- dns01:
webhook:
groupName: acme.yourdomain.tld
solverName: hetzner
config:
secretName: hetzner-secret
# zoneName: example.com # optional: auto-detected if omitted
# apiUrl: https://api.hetzner.cloud/v1 # optional: defaults to Hetzner Cloud API
# secretKey: api-token # optional: defaults to "api-token"In order to access the Hetzner Cloud API, the webhook needs an API token. Create a token at Hetzner Cloud Console with DNS write permissions.
If you choose another name for the secret than hetzner-secret, you must install the chart with a modified secretName value. RBAC policies ensure that no other secrets can be read by the webhook. Also modify the value of secretName in the [Cluster]Issuer.
The secret key in the secret defaults to api-token and can be overridden with the secretKey config field.
apiVersion: v1
kind: Secret
metadata:
name: hetzner-secret
namespace: cert-manager
type: Opaque
data:
api-token: <your-hetzner-cloud-api-token-base64-encoded>apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-cert
namespace: cert-manager
spec:
commonName: example.com
dnsNames:
- example.com
issuerRef:
name: letsencrypt-staging
kind: ClusterIssuer
secretName: example-certAll DNS providers must run the DNS01 provider conformance testing suite, else they will have undetermined behaviour when used with cert-manager.
It is essential that you configure and run the test suite when creating a DNS01 webhook.
First, you need to have a Hetzner Cloud account with access to DNS. You need to create an API token and have a registered and verified DNS zone.
Then replace the zoneName parameter in testdata/hetzner/config.json with your actual zone. You also must encode your API token into base64 and put it in testdata/hetzner/hetzner-secret.yml.
You can then run the test suite with:
./scripts/fetch-test-binaries.sh
TEST_ZONE_NAME=example.com. make testThe CI workflow (.github/workflows/build.yml) builds multi-arch Docker images for linux/amd64, linux/arm64, and linux/arm/v7 and pushes them to GHCR:
ghcr.io/sshine/cert-manager-webhook-hetzner
To build locally:
docker build -t cert-manager-webhook-hetzner .