TechnitiumSoftware/DnsServer · error · DnsServerException
The primary zone must be signed.
Error message
The primary zone must be signed.
What it means
Thrown by GenerateAndAddPrivateKey when the zone's DNSSEC status is Unsigned. Private keys can only live on a signed zone because their DNSKEY material has nowhere to be published otherwise; the guard blocks creating keys against an unsigned zone.
Source
Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:1045
{
deletedRecords.AddRange(zone.RemoveNSec3RecordsWithRRSig());
if (zone is SubDomainZone subDomainZone)
{
if (zone.IsEmpty)
_dnsServer.AuthZoneManager.RemoveSubDomainZone(zone.Name); //remove empty sub zone
else
subDomainZone.AutoUpdateState();
}
}
CommitAndIncrementSerial(deletedRecords);
}
public DnssecPrivateKey GenerateAndAddPrivateKey(DnssecPrivateKeyType keyType, DnssecAlgorithm algorithm, ushort rolloverDays, int keySize = -1)
{
if (_dnssecStatus == AuthZoneDnssecStatus.Unsigned)
throw new DnsServerException("The primary zone must be signed.");
int i = 0;
while (i++ < 5)
{
DnssecPrivateKey privateKey = DnssecPrivateKey.Create(algorithm, keyType, keySize);
privateKey.RolloverDays = rolloverDays;
lock (_dnssecPrivateKeys)
{
if (_dnssecPrivateKeys.TryAdd(privateKey.KeyTag, privateKey))
return privateKey;
}
}
throw new DnsServerException("Failed to add private key: key tag collision. Please try again.");
}
public void AddPrivateKey(DnssecPrivateKey privateKey)View on GitHub (pinned to d0484b6c1e)
Solutions
- Sign the zone first with SignZone, then call GenerateAndAddPrivateKey.
- If you have keys you want to import, sign the zone with those keys in one SignZone call instead.
- Guard the call with a DnssecStatus != Unsigned check.
Example fix
// before
var key = zone.GenerateAndAddPrivateKey(DnssecPrivateKeyType.KeySigningKey, DnssecAlgorithm.ECDSAP256SHA256, 365);
// after
if (zone.DnssecStatus == AuthZoneDnssecStatus.Unsigned)
throw new InvalidOperationException("Sign the zone before generating keys.");
var key = zone.GenerateAndAddPrivateKey(DnssecPrivateKeyType.KeySigningKey, DnssecAlgorithm.ECDSAP256SHA256, 365); Defensive patterns
Strategy: validation
Validate before calling
// Only generate keys on a signed zone
if (zone.DnssecStatus == AuthZoneDnssecStatus.Unsigned)
zone.SignZone(initialKeys, dnsKeyTtl, useNSec3: false);
var key = zone.GenerateAndAddPrivateKey(keyType, algorithm, rolloverDays); Type guard
static bool IsZoneSignedForKeys(ApexZone zone) =>
zone.DnssecStatus != AuthZoneDnssecStatus.Unsigned; Try / catch
try
{
key = zone.GenerateAndAddPrivateKey(keyType, algorithm, rolloverDays);
}
catch (DnsServerException ex) when (ex.Message == "The primary zone must be signed.")
{
zone.SignZone(initialKeys, dnsKeyTtl, useNSec3: false);
key = zone.GenerateAndAddPrivateKey(keyType, algorithm, rolloverDays);
} Prevention
- Order provisioning as: sign -> generate/import keys -> publish -> activate.
- Gate every key-management call behind a DnssecStatus != Unsigned check.
When it happens
Trigger: Calling GenerateAndAddPrivateKey(keyType, algorithm, rolloverDays) on a zone whose DnssecStatus is Unsigned.
Common situations: Provisioning keys before signing; an orchestration script that adds keys then signs, in the wrong order.
Related errors
- The zone must be signed.
- Cannot delete private key: only keys with Generated state ca
- Cannot convert to NSEC3: the zone must be signed with NSEC f
- Cannot update NSEC3 parameters: the zone must be signed with
- Failed to add {(privateKey.KeyType == DnssecPrivateKeyType.K
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/0cef248f62f80793.
Report an issue: GitHub.