TechnitiumSoftware/DnsServer · error · ArgumentException
The private key must be a Key Signing Key.
Error message
The private key must be a Key Signing Key.
What it means
Thrown by PrimaryZone.SignZone(kskPrivateKey, zskPrivateKey, ...) when the kskPrivateKey's KeyType is not DnssecPrivateKeyType.KeySigningKey. A KSK signs the DNSKEY RRset (and the DS chain), so passing a ZSK here would break the trust anchor. The guard raises ArgumentException with the 'kskPrivateKey' paramName before any signing work.
Source
Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:448
_dnsServer.LogManager.Write(ex);
}
finally
{
Timer dnssecTimer = _dnssecTimer;
if (dnssecTimer is not null)
{
lock (dnssecTimer)
{
dnssecTimer.Change(DNSSEC_TIMER_PERIODIC_INTERVAL, Timeout.Infinite);
}
}
}
}
public void SignZone(DnssecPrivateKey kskPrivateKey, DnssecPrivateKey zskPrivateKey, uint dnsKeyTtl, bool useNSec3, ushort iterations = 0, byte saltLength = 0)
{
if (kskPrivateKey.KeyType != DnssecPrivateKeyType.KeySigningKey)
throw new ArgumentException("The private key must be a Key Signing Key.", nameof(kskPrivateKey));
if (zskPrivateKey.KeyType != DnssecPrivateKeyType.ZoneSigningKey)
throw new ArgumentException("The private key must be a Zone Signing Key.", nameof(zskPrivateKey));
byte[] salt = null;
if (useNSec3)
{
if (saltLength > 32)
throw new ArgumentOutOfRangeException(nameof(saltLength), "NSEC3 salt length valid range is 0-32");
if (saltLength > 0)
{
salt = new byte[saltLength];
RandomNumberGenerator.Fill(salt);
}
else
{View on GitHub (pinned to d0484b6c1e)
Solutions
- Pass a key whose KeyType == DnssecPrivateKeyType.KeySigningKey as the first argument.
- When generating keys, create exactly one KSK and one ZSK and label them.
- Validate both keys' roles before calling SignZone.
Example fix
// before zone.SignZone(zsk1, zsk2, ttl, false); // after var ksk = keys.Single(k => k.KeyType == DnssecPrivateKeyType.KeySigningKey); var zsk = keys.Single(k => k.KeyType == DnssecPrivateKeyType.ZoneSigningKey); zone.SignZone(ksk, zsk, ttl, false);
Defensive patterns
Strategy: validation
Validate before calling
if (kskPrivateKey.KeyType != DnssecPrivateKeyType.KeySigningKey)
throw new ArgumentException("A KeySigningKey is required.");
zone.SignZone(kskPrivateKey, zskPrivateKey, ttl, useNSec3); Type guard
static bool IsKsk(DnssecPrivateKey k) => k.KeyType == DnssecPrivateKeyType.KeySigningKey;
Prevention
- Generate and label exactly one KSK and one ZSK.
- Validate the KSK role at key-load time.
- Pass keys by role, never by position alone.
When it happens
Trigger: primaryZone.SignZone(aZsk, anotherZsk, ...) where the first argument's KeyType != KeySigningKey.
Common situations: Swapping the two key arguments; generating two ZSKs by mistake; loading keys from storage without checking their declared role.
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 Zone Signing Key.
- NSEC3 salt length valid range is 0-32
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/85ce87c3f5d4e54c.
Report an issue: GitHub.