{"record":{"id":"7ab363fe221ed503","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-add-private-key-key-tag-collision-plea","errorCode":null,"errorMessage":"Failed to add private key: key tag collision. Please try again.","messagePattern":"Failed to add private key: key tag collision\\. Please try again\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimaryZone.cs","lineNumber":1060,"sourceCode":"        public DnssecPrivateKey GenerateAndAddPrivateKey(DnssecPrivateKeyType keyType, DnssecAlgorithm algorithm, ushort rolloverDays, int keySize = -1)\n        {\n            if (_dnssecStatus == AuthZoneDnssecStatus.Unsigned)\n                throw new DnsServerException(\"The primary zone must be signed.\");\n\n            int i = 0;\n            while (i++ < 5)\n            {\n                DnssecPrivateKey privateKey = DnssecPrivateKey.Create(algorithm, keyType, keySize);\n                privateKey.RolloverDays = rolloverDays;\n\n                lock (_dnssecPrivateKeys)\n                {\n                    if (_dnssecPrivateKeys.TryAdd(privateKey.KeyTag, privateKey))\n                        return privateKey;\n                }\n            }\n\n            throw new DnsServerException(\"Failed to add private key: key tag collision. Please try again.\");\n        }\n\n        public void AddPrivateKey(DnssecPrivateKey privateKey)\n        {\n            if (_dnssecStatus == AuthZoneDnssecStatus.Unsigned)\n                throw new DnsServerException(\"The primary zone must be signed.\");\n\n            lock (_dnssecPrivateKeys)\n            {\n                if (!_dnssecPrivateKeys.TryAdd(privateKey.KeyTag, privateKey))\n                    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.\");\n            }\n        }\n\n        public DnssecPrivateKey UpdatePrivateKey(ushort keyTag, ushort rolloverDays)\n        {\n            lock (_dnssecPrivateKeys)\n            {","sourceCodeStart":1042,"sourceCodeEnd":1078,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimaryZone.cs#L1042-L1078","documentation":"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.","triggerScenarios":"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.","commonSituations":"Long-lived zones with dozens of rolled-over keys filling the 65536-entry KeyTag space in unlucky clusters; degenerate RNG output.","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."],"exampleFix":"// before\nvar key = zone.GenerateAndAddPrivateKey(type, algo, 365);\n\n// after\nDnssecPrivateKey key;\nfor (int attempt = 0; attempt < 3; attempt++)\n{\n    try\n    {\n        key = zone.GenerateAndAddPrivateKey(type, algo, 365);\n        break;\n    }\n    catch (DnsServerException ex) when (ex.Message.Contains(\"key tag collision\"))\n    {\n        if (attempt == 2) throw;\n    }\n}","handlingStrategy":"retry","validationCode":"// Reduce collision odds by pruning stale Generated keys first\nvar stale = zone.DnssecPrivateKeys\n    .Where(k => k.State == DnssecPrivateKeyState.Generated)\n    .ToList();\nforeach (var k in stale) zone.DeletePrivateKey(k.KeyTag);","typeGuard":null,"tryCatchPattern":"DnssecPrivateKey key;\nfor (int attempt = 0; attempt < 5; attempt++)\n{\n    try\n    {\n        key = zone.GenerateAndAddPrivateKey(type, algo, rolloverDays);\n        break;\n    }\n    catch (DnsServerException ex) when (ex.Message.Contains(\"key tag collision\"))\n    {\n        if (attempt == 4) throw;\n    }\n}","preventionTips":["Prune unused Generated keys before generating new ones to free KeyTags.","Wrap GenerateAndAddPrivateKey in a small retry loop since the failure is RNG-dependent."],"tags":["dnssec","private-key","key-tag","retry","csharp"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}