TechnitiumSoftware/DnsServer · error · DnsServerException
Failed to add {(privateKey.KeyType == DnssecPrivateKeyType.K
Error message
Failed to add {(privateKey.KeyType == DnssecPrivateKeyType.KeySigningKey ? "KSK" : "ZSK")} private key: key tag collision. Please generate another private key and try again. What it means
Thrown by AddPrivateKey when _dnssecPrivateKeys.TryAdd fails because a key with the same KeyTag already exists. Unlike GenerateAndAddPrivateKey, this method imports a caller-supplied key and does not retry, so a single collision is fatal.
Source
Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:1071
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)
{
if (_dnssecStatus == AuthZoneDnssecStatus.Unsigned)
throw new DnsServerException("The primary zone must be signed.");
lock (_dnssecPrivateKeys)
{
if (!_dnssecPrivateKeys.TryAdd(privateKey.KeyTag, privateKey))
throw new DnsServerException($"Failed to add {(privateKey.KeyType == DnssecPrivateKeyType.KeySigningKey ? "KSK" : "ZSK")} private key: key tag collision. Please generate another private key and try again.");
}
}
public DnssecPrivateKey UpdatePrivateKey(ushort keyTag, ushort rolloverDays)
{
lock (_dnssecPrivateKeys)
{
if (!_dnssecPrivateKeys.TryGetValue(keyTag, out DnssecPrivateKey privateKey))
throw new DnsServerException("Cannot update private key: no such private key was found.");
privateKey.RolloverDays = rolloverDays;
return privateKey;
}
}
public void DeletePrivateKey(ushort keyTag)
{View on GitHub (pinned to d0484b6c1e)
Solutions
- Before adding, enumerate the zone's DnssecPrivateKeys and verify no entry shares the incoming KeyTag.
- If the key already exists and is the intended one, skip the add; otherwise delete the conflicting key first.
- Generate a fresh key with GenerateAndAddPrivateKey instead of importing one whose tag clashes.
Example fix
// before
zone.AddPrivateKey(privateKey);
// after
bool exists = zone.DnssecPrivateKeys.Any(k => k.KeyTag == privateKey.KeyTag);
if (!exists)
zone.AddPrivateKey(privateKey);
else
Console.WriteLine($"KeyTag {privateKey.KeyTag} already present; skipping."); Defensive patterns
Strategy: validation
Validate before calling
// Ensure the incoming KeyTag is not already present
bool exists = zone.DnssecPrivateKeys.Any(k => k.KeyTag == privateKey.KeyTag);
if (!exists)
zone.AddPrivateKey(privateKey); Type guard
static bool KeyTagIsFree(ApexZone zone, ushort keyTag) =>
!zone.DnssecPrivateKeys.Any(k => k.KeyTag == keyTag); Try / catch
try
{
zone.AddPrivateKey(privateKey);
}
catch (DnsServerException ex) when (ex.Message.Contains("key tag collision"))
{
// delete the conflicting key or generate a fresh one instead
} Prevention
- Diff the incoming keyset against zone.DnssecPrivateKeys by KeyTag before importing.
- Prefer GenerateAndAddPrivateKey for net-new keys to let the server retry collisions.
When it happens
Trigger: Calling AddPrivateKey with a DnssecPrivateKey whose KeyTag matches a key already stored on the zone.
Common situations: Re-importing a key that is already present; restoring from a backup that overlaps with the live key set; adding both members of a pre-computed KSK/ZSK pair whose tags coincide.
Related errors
- The primary zone must be signed.
- Failed to add private key: key tag collision. Please try aga
- Cannot update private key: no such private key was found.
- The zone must be signed.
- Cannot delete private key: no such private key was found.
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/81bd427f84454564.
Report an issue: GitHub.