TechnitiumSoftware/DnsServer · error · DnsServerException

Failed to transfer configuration: only the Primary node can

Error message

Failed to transfer configuration: only the Primary node can transfer the configuration.

What it means

TransferConfigAsync is restricted to the cluster Primary (GetSelfNode().Type == Primary). Only the Primary owns the authoritative configuration to push to Secondaries.

Source

Thrown at DnsServerCore/Cluster/ClusterManager.cs:878

            SaveConfigFile();

            //notify all secondary nodes
            TriggerNotifyAllSecondaryNodes();

            //trigger NS and SOA update for member zones only if secondary node domain name has changed
            if (secondaryNodeDomainChanged)
                TriggerRecordUpdateForClusterCatalogMemberZones();

            return secondaryNode;
        }

        public Task TransferConfigAsync(Stream zipStream, DateTime ifModifiedSince, ICollection<string> includeZones)
        {
            if (!ClusterInitialized)
                throw new DnsServerException("Failed to transfer configuration: the Cluster is not initialized.");

            if (GetSelfNode().Type != ClusterNodeType.Primary)
                throw new DnsServerException("Failed to transfer configuration: only the Primary node can transfer the configuration.");

            return _dnsWebService.BackupConfigAsync(zipStream: zipStream,
                                                    authConfig: true,
                                                    clusterConfig: false,
                                                    webServiceSettings: false,
                                                    dnsSettings: true,
                                                    logSettings: false,
                                                    zones: true,
                                                    allowedZones: true,
                                                    blockedZones: true,
                                                    blockLists: true,
                                                    apps: true,
                                                    scopes: false,
                                                    stats: false,
                                                    logs: false,
                                                    isConfigTransfer: true,
                                                    ifModifiedSince: ifModifiedSince,
                                                    includeZones: includeZones);

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Pull configuration from the current Primary only
  2. Re-resolve which node is Primary before each transfer
  3. Fix the Secondary's configured Primary URL

Example fix

// before
await clusterManager.TransferConfigAsync(stream, since, zones);

// after
if (clusterManager.GetSelfNode().Type != ClusterNodeType.Primary)
    return Redirect("Config transfer is served by the Primary node.");
await clusterManager.TransferConfigAsync(stream, since, zones);
Defensive patterns

Strategy: validation

Validate before calling

if (clusterManager.GetSelfNode().Type != ClusterNodeType.Primary)
    return BadRequest("Only the Primary serves config transfer.");
return await clusterManager.TransferConfigAsync(stream, ifModifiedSince, includeZones);

Try / catch

catch (DnsServerException ex) when (ex.Message.Contains("only the Primary node can transfer"))
{ /* rediscover Primary and retry */ }

Prevention

When it happens

Trigger: A Secondary node serving a config-transfer request; an L4 load balancer routing the pull to a non-Primary member; a role change after the client pinned the endpoint.

Common situations: Failover changing the Primary; client targeting a member IP instead of the Primary role; a misconfigured Secondary 'primary URL'.

Related errors


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