TechnitiumSoftware/DnsServer · error · DnsServerException

Invalid AXFR response was received.

Error message

Invalid AXFR response was received.

What it means

Thrown by SyncZoneTransferRecords when the received AXFR response fails structural validation: fewer than 2 records, first record is not SOA, first record name does not match zoneName, or first and last records are not equal (SOA bracketing). This is the response-side parser for incoming zone transfers from a remote primary.

Source

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

            //start incremental message
            xfrRecords.Add(currentSoaRecord);

            //write history
            for (int i = index; i < zoneHistory.Count; i++)
                xfrRecords.Add(zoneHistory[i]);

            //end incremental message
            xfrRecords.Add(currentSoaRecord);

            //condense
            return CondenseIncrementalZoneTransferRecords(zoneName, clientSoaRecord, xfrRecords);
        }

        public void SyncZoneTransferRecords(string zoneName, IReadOnlyList<DnsResourceRecord> xfrRecords)
        {
            if ((xfrRecords.Count < 2) || (xfrRecords[0].Type != DnsResourceRecordType.SOA) || !xfrRecords[0].Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase) || !xfrRecords[xfrRecords.Count - 1].Equals(xfrRecords[0]))
                throw new DnsServerException("Invalid AXFR response was received.");

            List<DnsResourceRecord> latestRecords = new List<DnsResourceRecord>(xfrRecords.Count);
            List<DnsResourceRecord> allGlueRecords = new List<DnsResourceRecord>(4);

            if (zoneName.Length == 0)
            {
                //root zone case
                for (int i = 1; i < xfrRecords.Count; i++)
                {
                    DnsResourceRecord record = xfrRecords[i];

                    switch (record.Type)
                    {
                        case DnsResourceRecordType.A:
                        case DnsResourceRecordType.AAAA:
                            if (!allGlueRecords.Contains(record))
                                allGlueRecords.Add(record);

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Validate the xfrRecords structure before calling SyncZoneTransferRecords: check count >= 2, first and last are SOA, first.Name == zoneName, and first.Equals(last).
  2. Re-request the full zone transfer from the primary if the response is malformed.
  3. Verify the primary server's zone name matches the secondary's configured zone name.
  4. Check network connectivity and TCP buffer sizes for large zone transfers.

Example fix

// before
authZoneManager.SyncZoneTransferRecords(zoneName, xfrRecords);

// after
if (xfrRecords.Count < 2
    || xfrRecords[0].Type != DnsResourceRecordType.SOA
    || !xfrRecords[0].Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)
    || !xfrRecords[^1].Equals(xfrRecords[0]))
{
    _logger.LogError("Invalid AXFR response for zone '{Zone}'; re-requesting.", zoneName);
    xfrRecords = await dnsClient.QueryZoneTransferAsync(zoneName); // retry
}
authZoneManager.SyncZoneTransferRecords(zoneName, xfrRecords);
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidAxfrResponse(string zoneName, IReadOnlyList<DnsResourceRecord> xfrRecords)
{
    return xfrRecords.Count >= 2
        && xfrRecords[0].Type == DnsResourceRecordType.SOA
        && xfrRecords[0].Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)
        && xfrRecords[^1].Equals(xfrRecords[0]);
}

if (!IsValidAxfrResponse(zoneName, xfrRecords))
    throw new InvalidOperationException("Invalid AXFR response structure.");

Type guard

static bool IsValidAxfrEnvelope(IReadOnlyList<DnsResourceRecord> records, string zoneName)
    => records.Count >= 2
       && records[0].Type == DnsResourceRecordType.SOA
       && records[0].Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)
       && records[^1].Equals(records[0]);

Try / catch

try
{
    authZoneManager.SyncZoneTransferRecords(zoneName, xfrRecords);
}
catch (DnsServerException ex) when (ex.Message.Contains("Invalid AXFR response"))
{
    logger.LogError("AXFR sync failed for '{Zone}'; response malformed. Retrying.", zoneName);
    xfrRecords = await dnsClient.QueryZoneTransferAsync(zoneName);
    authZoneManager.SyncZoneTransferRecords(zoneName, xfrRecords);
}

Prevention

When it happens

Trigger: Calling SyncZoneTransferRecords(zoneName, xfrRecords) with malformed xfrRecords: truncated transfer (count < 2), missing SOA header/footer, SOA name mismatch (wrong zone data received), or start/end SOA records that differ (incomplete or corrupted transfer). This processes data received from a remote server.

Common situations: Remote primary server is misbehaving (truncated response, wrong zone data); network corruption or TCP truncation of the transfer stream; zone name mismatch between secondary config and primary's actual zone; AXFR response from a non-standard DNS server that doesn't bracket with SOA.

Related errors


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