TechnitiumSoftware/DnsServer · error · DnsServerException
Failed to add private key: key tag collision. Please try aga
Error message
Failed to add private key: key tag collision. Please try again.
What it means
Thrown by GenerateAndAddPrivateKey after five consecutive attempts to generate a key whose KeyTag collides with an existing key. KeyTag is a 16-bit value, so collisions are possible once many keys accumulate; the method retries up to five times then gives up with this message.
Source
Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:1060
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)
{
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)
{View on GitHub (pinned to d0484b6c1e)
Solutions
- Retry the call; the RNG-dependent KeyTag will differ on a fresh attempt.
- Delete unused keys (those in Generated or Dead/Removed-equivalent states) to free their KeyTags before regenerating.
- If collisions recur, audit the key set for stale entries that can be purged.
Example fix
// before
var key = zone.GenerateAndAddPrivateKey(type, algo, 365);
// after
DnssecPrivateKey key;
for (int attempt = 0; attempt < 3; attempt++)
{
try
{
key = zone.GenerateAndAddPrivateKey(type, algo, 365);
break;
}
catch (DnsServerException ex) when (ex.Message.Contains("key tag collision"))
{
if (attempt == 2) throw;
}
} Defensive patterns
Strategy: retry
Validate before calling
// Reduce collision odds by pruning stale Generated keys first
var stale = zone.DnssecPrivateKeys
.Where(k => k.State == DnssecPrivateKeyState.Generated)
.ToList();
foreach (var k in stale) zone.DeletePrivateKey(k.KeyTag); Try / catch
DnssecPrivateKey key;
for (int attempt = 0; attempt < 5; attempt++)
{
try
{
key = zone.GenerateAndAddPrivateKey(type, algo, rolloverDays);
break;
}
catch (DnsServerException ex) when (ex.Message.Contains("key tag collision"))
{
if (attempt == 4) throw;
}
} Prevention
- Prune unused Generated keys before generating new ones to free KeyTags.
- Wrap GenerateAndAddPrivateKey in a small retry loop since the failure is RNG-dependent.
When it happens
Trigger: The zone already holds a large number of private keys, and each freshly generated key's computed KeyTag happens to match an existing one across all five attempts.
Common situations: Long-lived zones with dozens of rolled-over keys filling the 65536-entry KeyTag space in unlucky clusters; degenerate RNG output.
Related errors
- Failed to add {(privateKey.KeyType == DnssecPrivateKeyType.K
- The primary zone must be signed.
- 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/7ab363fe221ed503.
Report an issue: GitHub.