TechnitiumSoftware/DnsServer · error · InvalidOperationException

Cannot add record: a CNAME record cannot exists with other r

Error message

Cannot add record: a CNAME record cannot exists with other record types for the same name.

What it means

Inside AuthZone.TrySetRecords (internal), the CNAME case enforces RFC 1034 section 3.6.2: a CNAME resource record cannot coexist with any other record type at the same DNS name. If the zone's _entries dictionary is non-empty and does NOT already contain a CNAME entry (meaning other record types are present), setting a CNAME throws InvalidOperationException. This is a fundamental DNS protocol constraint, not an arbitrary library restriction.

Source

Thrown at DnsServerCore/Dns/Zones/AuthZone.cs:135

                    rrsigRecord.GetAuthGenericRecordInfo().LastUsedOn = utcNow;
                    newRecords.Add(rrsigRecord);
                }
            }

            return newRecords;
        }

        #endregion

        #region versioning

        internal bool TrySetRecords(DnsResourceRecordType type, IReadOnlyList<DnsResourceRecord> records, out IReadOnlyList<DnsResourceRecord> deletedRecords)
        {
            switch (type)
            {
                case DnsResourceRecordType.CNAME:
                    if ((!_entries.IsEmpty) && !_entries.ContainsKey(DnsResourceRecordType.CNAME))
                        throw new InvalidOperationException("Cannot add record: a CNAME record cannot exists with other record types for the same name.");

                    break;

                case DnsResourceRecordType.NSEC:
                case DnsResourceRecordType.RRSIG:
                    break; //ignore

                default:
                    if (_entries.ContainsKey(DnsResourceRecordType.CNAME))
                        throw new InvalidOperationException("Cannot add record: a CNAME record cannot exists with other record types for the same name.");

                    break;
            }

            if (_entries.TryGetValue(type, out IReadOnlyList<DnsResourceRecord> existingRecords))
            {
                deletedRecords = existingRecords;
                return _entries.TryUpdate(type, records, existingRecords);

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Delete all existing records for the name before setting a CNAME (call DeleteRecords for each existing type first).
  2. Use SetRecords with type=CNAME which routes through the same guard — clear _entries of conflicting types first.
  3. Switch to an A/AAAA record pointing to the target IP instead of using a CNAME if coexistence is required.
  4. Validate that _entries is empty or contains only CNAME before attempting the CNAME assignment.

Example fix

// before
zone.TrySetRecords(DnsResourceRecordType.CNAME, cnameRecords, out _);
// throws if A records exist

// after
foreach (var type in zone.GetRecordTypes())
    zone.DeleteRecords(type);
zone.TrySetRecords(DnsResourceRecordType.CNAME, cnameRecords, out _);
Defensive patterns

Strategy: validation

Validate before calling

// Before setting CNAME, ensure no other record types exist
bool hasOtherTypes = zone.GetRecordTypes().Any(t => t != DnsResourceRecordType.CNAME
    && t != DnsResourceRecordType.NSEC && t != DnsResourceRecordType.RRSIG);
if (hasOtherTypes)
    throw new InvalidOperationException("Cannot set CNAME: other record types exist. Delete them first.");
zone.SetRecords(DnsResourceRecordType.CNAME, cnameRecords);

Try / catch

try { zone.SetRecords(DnsResourceRecordType.CNAME, cnameRecords); }
catch (InvalidOperationException ex) when (ex.Message.Contains("CNAME"))
{ /* clear conflicting records and retry, or report to user */ }

Prevention

When it happens

Trigger: Calling the internal TrySetRecords method with type=DnsResourceRecordType.CNAME when the zone node (_entries) already contains records of other types (A, AAAA, MX, TXT, etc.). Typically reached indirectly through SetRecords or zone-transfer logic that routes through TrySetRecords.

Common situations: Migrating an A record to a CNAME alias without first deleting the existing A record; importing zone data from a misconfigured source; automated provisioning scripts that set CNAME without checking existing records; copying records between zones where the target already has records.

Related errors


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