TechnitiumSoftware/DnsServer · error · InvalidOperationException
Cannot set DNSSEC records.
Error message
Cannot set DNSSEC records.
What it means
Thrown by PrimarySubDomainZone.SetRecords() when type is DNSKEY, RRSIG, NSEC, NSEC3PARAM, or NSEC3. DNSSEC records are generated and maintained automatically by the signing engine (see _primaryZone.UpdateDnssecRecordsFor(...)); letting a caller write them directly would desync signatures, key rollover state, and NSEC/NSEC3 chains. This is a hard InvalidOperationException, not a domain DnsServerException, because it signals a misuse of the API rather than a data problem. The same guard exists in AddRecord/DeleteRecord for symmetry.
Source
Thrown at DnsServerCore/Dns/Zones/PrimarySubDomainZone.cs:87
if (record.GetAuthGenericRecordInfo().Disabled)
throw new DnsServerException("Cannot set records: disabling records in a signed zones is not supported.");
}
break;
}
}
switch (type)
{
case DnsResourceRecordType.SOA:
throw new InvalidOperationException("Cannot set SOA record on sub domain.");
case DnsResourceRecordType.DNSKEY:
case DnsResourceRecordType.RRSIG:
case DnsResourceRecordType.NSEC:
case DnsResourceRecordType.NSEC3PARAM:
case DnsResourceRecordType.NSEC3:
throw new InvalidOperationException("Cannot set DNSSEC records.");
case DnsResourceRecordType.FWD:
throw new DnsServerException("The record type is not supported by primary zones.");
default:
if (records[0].OriginalTtlValue > _primaryZone.GetZoneSoaExpire())
throw new DnsServerException("Cannot set records: TTL cannot be greater than SOA EXPIRE.");
if (!TrySetRecords(type, records, out IReadOnlyList<DnsResourceRecord> deletedRecords))
throw new DnsServerException("Cannot set records. Please try again.");
_primaryZone.CommitAndIncrementSerial(deletedRecords, records);
if (_primaryZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)
_primaryZone.UpdateDnssecRecordsFor(this, type);
_primaryZone.TriggerNotify();
break;View on GitHub (pinned to d0484b6c1e)
Solutions
- Exclude DNSSEC record types (DNSKEY, RRSIG, NSEC, NSEC3PARAM, NSEC3) from any SetRecords call; let the signing engine produce them.
- When importing a signed zone, import only the user records (A, AAAA, MX, etc.) and re-sign on the server.
- If publishing a trust anchor, use the DS record at the parent, not DNSKEY at the child.
Example fix
// before
foreach (var grp in importedRecords.GroupBy(r => r.Type))
subZone.SetRecords(grp.Key, grp.ToList());
// after
var dnssecTypes = new[] { DnsResourceRecordType.DNSKEY, DnsResourceRecordType.RRSIG,
DnsResourceRecordType.NSEC, DnsResourceRecordType.NSEC3PARAM, DnsResourceRecordType.NSEC3 };
foreach (var grp in importedRecords.GroupBy(r => r.Type))
if (!dnssecTypes.Contains(grp.Key))
subZone.SetRecords(grp.Key, grp.ToList()); Defensive patterns
Strategy: validation
Validate before calling
var dnssecTypes = new HashSet<DnsResourceRecordType> { DnsResourceRecordType.DNSKEY, DnsResourceRecordType.RRSIG, DnsResourceRecordType.NSEC, DnsResourceRecordType.NSEC3PARAM, DnsResourceRecordType.NSEC3 };
if (dnssecTypes.Contains(type)) throw new InvalidOperationException("DNSSEC records are managed by the signing engine.");
zone.SetRecords(type, records); Type guard
static bool IsDnssecRecordType(DnsResourceRecordType t) => t == DnsResourceRecordType.DNSKEY || t == DnsResourceRecordType.RRSIG || t == DnsResourceRecordType.NSEC || t == DnsResourceRecordType.NSEC3PARAM || t == DnsResourceRecordType.NSEC3;
Try / catch
try { zone.SetRecords(type, records); }
catch (InvalidOperationException) when (IsDnssecRecordType(type)) { /* skip; signing engine owns these */ } Prevention
- Strip DNSSEC record types from all imports before calling SetRecords.
- Let the server's signing engine be the sole writer of DNSKEY/RRSIG/NSEC*.
- Publish trust anchors via DS at the parent, not DNSKEY at the child.
When it happens
Trigger: subZone.SetRecords(DnsResourceRecordType.DNSKEY|RRSIG|NSEC|NSEC3PARAM|NSEC3, records) — e.g. importing a signed zone file verbatim, or a client trying to publish its own DNSKEY/DS material directly.
Common situations: AXFR-style import of an already-signed zone; manual key management attempts; test fixtures that include DNSSEC records.
Related errors
- Cannot add DNSSEC record.
- The record type is not supported by DNSSEC signed primary zo
- Cannot set records: disabling records in a signed zones is n
- Cannot set SOA record on sub domain.
- Cannot add record: disabling records in a signed zones is no
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/d097a032bdbc3283.
Report an issue: GitHub.