A zone accepts two FWD records with the same forwarder, protocol and priority that differ only by dnssecValidation. Neither can then be addressed individually: dnssecValidation is not part of the record match for delete or update, so the wrong record is affected and the call still returns status: "ok".
Reproduced identically on 15.4.0 and on 15.2 (latest, digest sha256:99c250f0…). Fresh container, empty config.
Setup
B=http://127.0.0.1:5380; T=<token>; Z=fwdcollide.example.net
curl -s "$B/api/zones/create?token=$T&zone=$Z&type=Forwarder&initializeForwarder=false"
# both accepted
curl -s "$B/api/zones/records/add?token=$T&domain=$Z&zone=$Z&type=FWD&ttl=3600\
&forwarder=1.1.1.1&protocol=Udp&forwarderPriority=1&dnssecValidation=true"
curl -s "$B/api/zones/records/add?token=$T&domain=$Z&zone=$Z&type=FWD&ttl=3600\
&forwarder=1.1.1.1&protocol=Udp&forwarderPriority=1&dnssecValidation=false"
1. Delete removes the wrong record
curl -s "$B/api/zones/records/delete?token=$T&domain=$Z&zone=$Z&type=FWD\
&forwarder=1.1.1.1&protocol=Udp&forwarderPriority=1&dnssecValidation=<true|false>"
The first-created record is deleted regardless of the value sent:
| created order |
dnssecValidation sent |
deleted |
| true, false |
true |
true |
| true, false |
false |
true |
| false, true |
true |
false |
| false, true |
false |
false |
All four return status: "ok". A caller asking to delete one record can silently destroy the other and be told it succeeded.
2. Update merges the two into one
curl -s "$B/api/zones/records/update?token=$T&domain=$Z&zone=$Z&type=FWD\
&forwarder=1.1.1.1&protocol=Udp&forwarderPriority=1&dnssecValidation=false"
Two records before, one after. The update locates a record by forwarder/protocol/priority, sets dnssecValidation=false, and the result coincides with the existing false record — so a record is lost, again reported as "ok".
There is no newDnssecValidation to supply the old value as an identifier, the way newForwarder / newProtocol / newForwarderPriority do for the other fields; sending it alongside dnssecValidation=true on a true record left the record unchanged, so it appears to be ignored.
3. Omitting dnssecValidation on update resets it
On a single record with dnssecValidation=true, a TTL-only update:
curl -s "$B/api/zones/records/update?token=$T&domain=$Z&zone=$Z&type=FWD\
&forwarder=1.1.1.1&protocol=Udp&forwarderPriority=1&ttl=7200"
leaves dnssecValidation=false. This may be intended (an omitted boolean defaulting to false), but it means any client sending only changed fields silently disables DNSSEC validation.
Workaround
Give each forwarder a distinct forwarderPriority, forwarder or protocol — records differing by any of those are addressed correctly.
Found while adding FWD support to a Terraform provider, where these map to a user destroying or modifying one of two declared forwarders. Happy to test a patch against the reproducer.
A zone accepts two
FWDrecords with the same forwarder, protocol and priority that differ only bydnssecValidation. Neither can then be addressed individually:dnssecValidationis not part of the record match for delete or update, so the wrong record is affected and the call still returnsstatus: "ok".Reproduced identically on 15.4.0 and on 15.2 (
latest, digestsha256:99c250f0…). Fresh container, empty config.Setup
1. Delete removes the wrong record
The first-created record is deleted regardless of the value sent:
dnssecValidationsenttruefalsetruefalseAll four return
status: "ok". A caller asking to delete one record can silently destroy the other and be told it succeeded.2. Update merges the two into one
Two records before, one after. The update locates a record by forwarder/protocol/priority, sets
dnssecValidation=false, and the result coincides with the existingfalserecord — so a record is lost, again reported as"ok".There is no
newDnssecValidationto supply the old value as an identifier, the waynewForwarder/newProtocol/newForwarderPrioritydo for the other fields; sending it alongsidednssecValidation=trueon atruerecord left the record unchanged, so it appears to be ignored.3. Omitting
dnssecValidationon update resets itOn a single record with
dnssecValidation=true, a TTL-only update:leaves
dnssecValidation=false. This may be intended (an omitted boolean defaulting to false), but it means any client sending only changed fields silently disables DNSSEC validation.Workaround
Give each forwarder a distinct
forwarderPriority, forwarder or protocol — records differing by any of those are addressed correctly.Found while adding FWD support to a Terraform provider, where these map to a user destroying or modifying one of two declared forwarders. Happy to test a patch against the reproducer.