TechnitiumSoftware/DnsServer · error · ArgumentException
The private keys must contain at least one Zone Signing Key.
Error message
The private keys must contain at least one Zone Signing Key.
What it means
Companion to error 516: thrown by the collection overload PrimaryZone.SignZone when no key in dnssecPrivateKeys has KeyType == ZoneSigningKey. Without a ZSK the non-DNSKEY RRsets cannot be signed, so the guard raises ArgumentException(nameof(dnssecPrivateKeys)) right after the KSK check.
Source
Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:510
foreach (DnssecPrivateKey dnssecPrivateKey in dnssecPrivateKeys)
{
switch (dnssecPrivateKey.KeyType)
{
case DnssecPrivateKeyType.KeySigningKey:
foundKsk = true;
break;
case DnssecPrivateKeyType.ZoneSigningKey:
foundZsk = true;
break;
}
}
if (!foundKsk)
throw new ArgumentException("The private keys must contain at least one Key Signing Key.", nameof(dnssecPrivateKeys));
if (!foundZsk)
throw new ArgumentException("The private keys must contain at least one Zone Signing Key.", nameof(dnssecPrivateKeys));
//load dnssec private keys
_dnssecPrivateKeys = new Dictionary<ushort, DnssecPrivateKey>(dnssecPrivateKeys.Count);
foreach (DnssecPrivateKey dnssecPrivateKey in dnssecPrivateKeys)
_dnssecPrivateKeys.Add(dnssecPrivateKey.KeyTag, dnssecPrivateKey);
//start zone signing
List<DnsResourceRecord> addedRecords = new List<DnsResourceRecord>();
List<DnsResourceRecord> deletedRecords = new List<DnsResourceRecord>();
try
{
IReadOnlyList<AuthZone> zones = _dnsServer.AuthZoneManager.GetApexZoneWithSubDomainZones(_name);
//find max record ttl in zone
uint maxRecordTtl = 0;
View on GitHub (pinned to d0484b6c1e)
Solutions
- Include at least one ZoneSigningKey in the collection.
- Validate both roles are present before signing.
- Use the (ksk, zsk) overload for the common single-KSK/single-ZSK case.
Example fix
// before
zone.SignZone(new[] { ksk }, ttl, false);
// after
zone.SignZone(new[] { ksk, zsk }, ttl, false); Defensive patterns
Strategy: validation
Validate before calling
if (!dnssecPrivateKeys.Any(k => k.KeyType == DnssecPrivateKeyType.ZoneSigningKey))
throw new ArgumentException("At least one ZSK required.");
zone.SignZone(dnssecPrivateKeys, ttl, useNSec3); Type guard
static bool HasZsk(IEnumerable<DnssecPrivateKey> ks) => ks.Any(k => k.KeyType == DnssecPrivateKeyType.ZoneSigningKey);
Prevention
- Ensure the key set contains at least one ZSK.
- Provision a ZSK whenever you create a KSK.
- Validate both roles at key-collection build time.
When it happens
Trigger: zone.SignZone(kskOnlyList, ...) — a collection with only KeySigningKey entries.
Common situations: Creating one KSK and forgetting the ZSK; key-roll scripts that provision only the trust anchor.
Related errors
- Cannot delete DNSSEC records.
- Cannot update DNSSEC records.
- Cannot update record: disabling records in a signed zones is
- The private key must be a Key Signing Key.
- The private key must be a Zone Signing Key.
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/04864fd42677ef18.
Report an issue: GitHub.