TechnitiumSoftware/DnsServer · error · InvalidOperationException

Cannot set {type} record at zone apex.

Error message

Cannot set {type} record at zone apex.

What it means

Thrown as InvalidOperationException by PrimaryZone.SetRecords() when the requested type is CNAME or DS. A CNAME at the zone apex is illegal (RFC 1034: apex must have SOA/NS) and a DS record is managed by the parent zone, not set locally at the apex. This is a programming/usage error, not an operational condition.

Source

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

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

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

                        break;
                }
            }

            switch (type)
            {
                case DnsResourceRecordType.CNAME:
                case DnsResourceRecordType.DS:
                    throw new InvalidOperationException("Cannot set " + type.ToString() + " record at zone apex.");

                case DnsResourceRecordType.SOA:
                    if ((records.Count != 1) || !records[0].Name.Equals(_name, StringComparison.OrdinalIgnoreCase))
                        throw new InvalidOperationException("Invalid SOA record.");

                    DnsResourceRecord newSoaRecord = records[0];
                    DnsSOARecordData newSoa = newSoaRecord.RDATA as DnsSOARecordData;

                    if (newSoaRecord.OriginalTtlValue > newSoa.Expire)
                        throw new DnsServerException("Cannot set record: TTL cannot be greater than SOA EXPIRE.");

                    if (newSoa.Retry > newSoa.Refresh)
                        throw new DnsServerException("Cannot set record: SOA RETRY cannot be greater than SOA REFRESH.");

                    if (newSoa.Refresh > newSoa.Expire)
                        throw new DnsServerException("Cannot set record: SOA REFRESH cannot be greater than SOA EXPIRE.");

                    //remove any record info except serial date scheme and comments

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Never call SetRecords with CNAME or DS on a primary zone; CNAME is illegal at the apex and DS belongs in the parent zone.
  2. Guard the call site with a type check that skips CNAME/DS.
  3. Use the zone's specific APIs (parent-zone DS management, non-apex CNAME handling) instead of SetRecords for these types.

Example fix

// before
zone.SetRecords(type, records); // throws for CNAME/DS

// after
if (type != DnsResourceRecordType.CNAME && type != DnsResourceRecordType.DS)
    zone.SetRecords(type, records);
Defensive patterns

Strategy: type-guard

Validate before calling

if (type == DnsResourceRecordType.CNAME || type == DnsResourceRecordType.DS)
    throw new ArgumentException($"{type} cannot be set at the zone apex.");

zone.SetRecords(type, records);

Type guard

static bool IsApexSettable(DnsResourceRecordType t) =>
    t != DnsResourceRecordType.CNAME && t != DnsResourceRecordType.DS;

Try / catch

try { zone.SetRecords(type, records); }
catch (InvalidOperationException ex) when (ex.Message.Contains("record at zone apex"))
{ Log.Error($"{type} is illegal at the apex: {ex.Message}"); }

Prevention

When it happens

Trigger: Calling SetRecords(DnsResourceRecordType.CNAME, ...) or SetRecords(DnsResourceRecordType.DS, ...) on a primary zone (these types resolve to the apex-rejection branch in the switch).

Common situations: Generic record-management code that iterates all record types and calls SetRecords for each without excluding CNAME/DS; importing a foreign zone file that places a CNAME at the apex.

Related errors


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