TechnitiumSoftware/DnsServer · error · InvalidOperationException

No SOA record was found for IXFR.

Error message

No SOA record was found for IXFR.

What it means

Thrown by QueryIncrementalZoneTransferRecords when the zone exists but apexZone.GetRecords(SOA).Count != 1. IXFR requires exactly one SOA record to determine the current serial and compute incremental diffs. Zones without a valid single SOA (stub, catalog, or corrupted zones) cannot support incremental transfer.

Source

Thrown at DnsServerCore/Dns/ZoneManagers/AuthZoneManager.cs:2531

                }
            }

            //end message
            xfrRecords.Add(soaRecord);

            return xfrRecords;
        }

        public IReadOnlyList<DnsResourceRecord> QueryIncrementalZoneTransferRecords(string zoneName, DnsResourceRecord clientSoaRecord)
        {
            AuthZoneInfo authZone = GetAuthZoneInfo(zoneName, true);
            if (authZone is null)
                throw new InvalidOperationException("Zone was not found: " + zoneName);

            //primary, secondary, forwarder, and catalog zones support zone transfer
            IReadOnlyList<DnsResourceRecord> soaRecords = authZone.ApexZone.GetRecords(DnsResourceRecordType.SOA);
            if (soaRecords.Count != 1)
                throw new InvalidOperationException("No SOA record was found for IXFR.");

            DnsResourceRecord currentSoaRecord = soaRecords[0];
            uint clientSerial = (clientSoaRecord.RDATA as DnsSOARecordData).Serial;

            if (clientSerial == (currentSoaRecord.RDATA as DnsSOARecordData).Serial)
            {
                //zone not modified
                return [currentSoaRecord];
            }

            //find history record start from client serial
            IReadOnlyList<DnsResourceRecord> zoneHistory = authZone.ZoneHistory;

            int index = 0;
            while (index < zoneHistory.Count)
            {
                //check difference sequence
                if ((zoneHistory[index].RDATA as DnsSOARecordData).Serial == clientSerial)

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Verify the zone has exactly one SOA record before requesting IXFR.
  2. For zones without SOA, use full AXFR or the zone-type-specific transfer mechanism.
  3. Repair corrupted zone files to ensure exactly one SOA at the apex.
  4. Check zone type: stub and certain catalog zones do not support IXFR.

Example fix

// before
var ixfrRecords = authZoneManager.QueryIncrementalZoneTransferRecords(zoneName, clientSoaRecord);

// after
AuthZoneInfo info = authZoneManager.GetAuthZoneInfo(zoneName, true);
if (info is null)
    throw new InvalidOperationException("Zone not found.");
var soaRecords = info.ApexZone.GetRecords(DnsResourceRecordType.SOA);
if (soaRecords.Count != 1)
    return authZoneManager.QueryZoneTransferRecords(zoneName); // fall back to AXFR
var ixfrRecords = authZoneManager.QueryIncrementalZoneTransferRecords(zoneName, clientSoaRecord);
Defensive patterns

Strategy: validation

Validate before calling

AuthZoneInfo info = authZoneManager.GetAuthZoneInfo(zoneName, true);
if (info is null)
    throw new InvalidOperationException("Zone not found.");
var soaRecords = info.ApexZone.GetRecords(DnsResourceRecordType.SOA);
if (soaRecords.Count != 1)
    throw new InvalidOperationException($"Zone has {soaRecords.Count} SOA records; IXFR requires exactly one.");

Type guard

static bool ZoneHasSingleSoa(AuthZoneManager mgr, string zoneName)
{
    AuthZoneInfo info = mgr.GetAuthZoneInfo(zoneName);
    if (info is null) return false;
    return info.ApexZone.GetRecords(DnsResourceRecordType.SOA).Count == 1;
}

Try / catch

try
{
    var records = authZoneManager.QueryIncrementalZoneTransferRecords(zoneName, clientSoaRecord);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("No SOA record was found for IXFR"))
{
    logger.LogWarning("IXFR not possible for '{Zone}': no single SOA; using AXFR.", zoneName);
    records = authZoneManager.QueryZoneTransferRecords(zoneName);
}

Prevention

When it happens

Trigger: Calling QueryIncrementalZoneTransferRecords on a zone that has zero or multiple SOA records. The zone passes the null check (error 414) but fails the SOA integrity check. This includes catalog zones (which do support IXFR per the comment but only through a different path) and stub zones (no SOA).

Common situations: Stub zone queried for IXFR (no SOA); zone corruption causing missing/duplicate SOA; zone in transition (being converted between types); catalog zone edge case where the comment notes catalogs support transfer but SOA check still applies.

Related errors


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