TechnitiumSoftware/DnsServer · error · InvalidOperationException

Cannot set DS record at zone apex.

Error message

Cannot set DS record at zone apex.

What it means

Thrown as InvalidOperationException by PrimaryZone.AddRecord() when the record type is DS. A DS record at the zone apex is not added locally; it is published in the parent zone to establish the chain of trust. AddRecord therefore refuses DS on a primary (apex) zone. This is a programming/usage error.

Source

Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:2644

                    case DnsResourceRecordType.ANAME:
                    case DnsResourceRecordType.APP:
                        throw new DnsServerException("The record type is not supported by DNSSEC signed primary zones.");

                    default:
                        if (record.GetAuthGenericRecordInfo().Disabled)
                            throw new DnsServerException("Cannot add record: disabling records in a signed zones is not supported.");

                        break;
                }
            }

            switch (record.Type)
            {
                case DnsResourceRecordType.APP:
                    throw new InvalidOperationException("Cannot add record: use SetRecords() for " + record.Type.ToString() + " record");

                case DnsResourceRecordType.DS:
                    throw new InvalidOperationException("Cannot set DS record at zone apex.");

                case DnsResourceRecordType.DNSKEY:
                case DnsResourceRecordType.RRSIG:
                case DnsResourceRecordType.NSEC:
                case DnsResourceRecordType.NSEC3PARAM:
                case DnsResourceRecordType.NSEC3:
                    throw new InvalidOperationException("Cannot add DNSSEC record.");

                case DnsResourceRecordType.FWD:
                    throw new DnsServerException("The record type is not supported by primary zones.");

                default:
                    if (record.OriginalTtlValue > GetZoneSoaExpire())
                        throw new DnsServerException("Cannot add record: TTL cannot be greater than SOA EXPIRE.");

                    AddRecord(record, out IReadOnlyList<DnsResourceRecord> addedRecords, out IReadOnlyList<DnsResourceRecord> deletedRecords);

                    if (addedRecords.Count > 0)

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Do not add DS records to the child (primary) zone; publish the DS in the parent zone instead.
  2. Use the DNSSEC parent-zone DS management API to install the DS for chain-of-trust.
  3. Filter DS out of any AddRecord input on a primary zone.

Example fix

// before
zone.AddRecord(dsRecord); // throws: DS goes in parent zone

// after
parentZone.AddRecord(dsRecord); // install DS in the parent zone
Defensive patterns

Strategy: type-guard

Validate before calling

if (record.Type == DnsResourceRecordType.DS)
    throw new ArgumentException("DS records are published in the parent zone, not added here.");

zone.AddRecord(record);

Type guard

static bool IsAddableAtApex(DnsResourceRecordType t) =>
    t != DnsResourceRecordType.DS;

Try / catch

try { zone.AddRecord(record); }
catch (InvalidOperationException ex) when (ex.Message == "Cannot set DS record at zone apex.")
{ Log.Error("Add DS to the parent zone instead."); }

Prevention

When it happens

Trigger: Calling AddRecord with a record whose Type is DnsResourceRecordType.DS on a primary zone.

Common situations: Automation that adds DS records to the child zone instead of the parent; importing a zone bundle that includes parent-side DS records.

Related errors


AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13). Data as JSON: /api/errors/9ce3a2bd052d4fde. Report an issue: GitHub.