TechnitiumSoftware/DnsServer · error · InvalidOperationException
Cannot set SOA record on sub domain.
Error message
Cannot set SOA record on sub domain.
What it means
Thrown by PrimarySubDomainZone.SetRecords() when type is DnsResourceRecordType.SOA. A sub-domain zone is a delegated node inside a primary zone and shares its parent's SOA — there is no independent SOA for the sub-domain, and the parent's SOA (serial, timers, name server) is the authoritative one. Setting an SOA at the sub-domain level would create an ambiguous, non-RFC-compliant delegation, so the API hard-rejects it with InvalidOperationException. To change SOA values, edit the parent PrimaryZone's SOA via its own SetRecords(SOA,...).
Source
Thrown at DnsServerCore/Dns/Zones/PrimarySubDomainZone.cs:80
case DnsResourceRecordType.ANAME:
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.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.");
View on GitHub (pinned to d0484b6c1e)
Solutions
- Never call SetRecords(SOA) on a PrimarySubDomainZone; edit the parent PrimaryZone's SOA instead.
- Skip SOA (and NS-of-parent) when applying a record set to a sub-domain zone.
- If importing, route SOA only to the zone apex, not to delegated sub-nodes.
Example fix
// before
subZone.SetRecords(DnsResourceRecordType.SOA, new[] { soaRecord });
// after
// SOA lives on the parent primary zone
primaryZone.SetRecords(DnsResourceRecordType.SOA, new[] { soaRecord }); Defensive patterns
Strategy: validation
Validate before calling
if (type == DnsResourceRecordType.SOA)
throw new InvalidOperationException("SOA belongs to the parent primary zone, not the sub-domain.");
zone.SetRecords(type, records); Type guard
static bool IsAllowedSubDomainType(DnsResourceRecordType type) => type != DnsResourceRecordType.SOA;
Try / catch
try { zone.SetRecords(type, records); }
catch (InvalidOperationException) when (type == DnsResourceRecordType.SOA) { /* redirect to parent primary zone SetRecords(SOA) */ } Prevention
- Never target a PrimarySubDomainZone with SOA; edit the parent PrimaryZone's SOA.
- In importers, write SOA only to the zone apex.
- Treat sub-domain zones as leaf RRset containers, not apex-capable zones.
When it happens
Trigger: Calling subDomainZone.SetRecords(DnsResourceRecordType.SOA, records) — e.g. an import that pushes an SOA into every node, or a generic 'set records' routine that does not skip SOA for sub-domains.
Common situations: Zone-file importers that write SOA to each node; copy-paste of apex records into a delegation; tooling that treats every zone object as apex-capable.
Related errors
- Cannot set DNSSEC records.
- Cannot add DNSSEC record.
- Cannot update record: use SetRecords() for {0} record
- The record type is not supported by DNSSEC signed primary zo
- Cannot set records: disabling records in a signed zones is n
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/a5d5a36ad66be22f.
Report an issue: GitHub.