TechnitiumSoftware/DnsServer · error · ArgumentException

The private keys must contain at least one Key Signing Key.

Error message

The private keys must contain at least one Key Signing Key.

What it means

Thrown by the collection overload PrimaryZone.SignZone after scanning all dnssecPrivateKeys and finding no entry with KeyType == KeySigningKey. A valid signing set must contain at least one KSK (to produce the DNSKEY RRset signature and DS). The guard raises ArgumentException(nameof(dnssecPrivateKeys)).

Source

Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:507

            bool foundKsk = false;
            bool foundZsk = false;

            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);

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Include at least one KeySigningKey in the collection passed to SignZone.
  2. Validate the collection has both a KSK and a ZSK before calling.
  3. Use the (ksk, zsk) overload if you only ever sign with one of each.

Example fix

// before
zone.SignZone(zsks, ttl, false);

// after
var signingKeys = new[] { ksk }.Concat(zsks);
zone.SignZone(signingKeys.ToList(), ttl, false);
Defensive patterns

Strategy: validation

Validate before calling

if (!dnssecPrivateKeys.Any(k => k.KeyType == DnssecPrivateKeyType.KeySigningKey))
    throw new ArgumentException("At least one KSK required.");
zone.SignZone(dnssecPrivateKeys, ttl, useNSec3);

Type guard

static bool HasKsk(IEnumerable<DnssecPrivateKey> ks) => ks.Any(k => k.KeyType == DnssecPrivateKeyType.KeySigningKey);

Prevention

When it happens

Trigger: zone.SignZone(zskOnlyList, ...) — a collection with only ZoneSigningKey entries (or unknown types).

Common situations: Generating a batch of ZSKs and forgetting the KSK; loading keys filtered to the wrong role.

Related errors


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