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

  1. Retry the call; the RNG-dependent KeyTag will differ on a fresh attempt.
  2. Delete unused keys (those in Generated or Dead/Removed-equivalent states) to free their KeyTags before regenerating.
  3. 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

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


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