it seems the ddclient hetznerDNS is using the wrong API endpoint when it comes to update an record that is already added. There is:
https://docs.hetzner.cloud/reference/cloud#tag/zone-rrsets/update_zone_rrset
Update an RRSet�Copy link
Updates an RRSet in the Zone.
(this is used by the script)
and there is:
https://docs.hetzner.cloud/reference/cloud#tag/zone-rrset-actions/set_zone_rrset_records
Set Records of an RRSet�Copy link
Overwrites the resource records (RRs) of an existing RRSet in the Zone.
debug log with the current script:
<163>1 2026-02-19T00:00:26+01:00 ddclient 93808 - [meta sequenceId="4"] Account 1d46bcb5-5b5c-408a-9d6b-dfeeb81a1cf4 [hetzner - Hetzner] error updating record: HTTP 422 - {
"error": {
"code": "invalid_input",
"message": "can't update records with this endpoint",
"details": null
}
}
<165>1 2026-02-19T00:00:26+01:00 ddclient 93808 - [meta sequenceId="5"] Account 1d46bcb5-5b5c-408a-9d6b-dfeeb81a1cf4 [hetzner - Hetzner] not modified
<165>1 2026-02-19T00:00:56+01:00 ddclient 93808 - [meta sequenceId="6"] Account 1d46bcb5-5b5c-408a-9d6b-dfeeb81a1cf4 [hetzner - Hetzner] executing
<165>1 2026-02-19T00:00:56+01:00 ddclient 93808 - [meta sequenceId="7"] Account 1d46bcb5-5b5c-408a-9d6b-dfeeb81a1cf4 [hetzner - Hetzner] found zone ID for
<165>1 2026-02-19T00:00:56+01:00 ddclient 93808 - [meta sequenceId="8"] Account 1d46bcb5-5b5c-408a-9d6b-dfeeb81a1cf4 [hetzner - Hetzner] updating (record: , type: A) to
Its obvious I guess, it says cant update record with this endpoint.
I changed the script now to:
def _update_record(self, headers, zone_id, record_name, record_type, address):
"""Update existing record with new address"""
url = f"{self._api_base}/zones/{zone_id}/rrsets/{record_name}/A/actions/set_records"
data = {
'records': [{'value': str(address)}],
#'ttl': int(self.settings.get('ttl', 300))
}
->>I had to comment out the ttl, because it gave "404" from the api and Im not sure how to properly set it.
Now debug log looks like this:
2026-02-19T11:29:49NoticeddclientAccount d8833bf7-d6f9-48d3-a1e9-8139e2e229fc [hetzner - Hetzner] not modified
}
}
]
}
"type": "zone"
"id": ,
{
"resources": [
"error": null,
"finished": null,
"started": "2026-02-19T10:29:49Z",
"progress": 0,
"command": "set_rrset_records",
"status": "running",
"id": ,
"action": {
2026-02-19T11:29:49ErrorddclientAccount d8833bf7-d6f9-48d3-a1e9-8139e2e229fc [hetzner - Hetzner] error updating record: HTTP 201 - {
it says "error" but and I can see inside the hetzner api console:
zone.rrset.set_records
System ?
4 Minutes
before this change there was nothing.
could you fix this please?
Use the "native" DynDNS backend - there are two Hetzner DNS variants - the old "legacy" and the new one.
it is set to native and HetznerDNS not HetznerDNS legacy
1.: url = f"{self._api_base}/zones/{zone_id}/rrsets/{record_name}/{record_type}"
2(legacy): url = f"{self._api_base}/records/{record_id}"
3(working): url = f"{self._api_base}/zones/{zone_id}/rrsets/{record_name}/A/actions/set_records"
verify here:
https://github.com/opnsense/plugins/blob/master/dns/ddclient/src/opnsense/scripts/ddclient/lib/account/hetzner.py
legacy code is still in this python script, somewhere below
In that case, you should create a bug report on github for the plugin: https://github.com/opnsense/plugins/issues