{"record":{"id":"81bd427f84454564","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-add-privatekey-keytype-dnssecprivat","errorCode":null,"errorMessage":"Failed to add {(privateKey.KeyType == DnssecPrivateKeyType.KeySigningKey ? \"KSK\" : \"ZSK\")} private key: key tag collision. Please generate another private key and try again.","messagePattern":"Failed to add (.+?) private key: key tag collision\\. Please generate another private key and try again\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimaryZone.cs","lineNumber":1071,"sourceCode":"                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            {\n                if (!_dnssecPrivateKeys.TryGetValue(keyTag, out DnssecPrivateKey privateKey))\n                    throw new DnsServerException(\"Cannot update private key: no such private key was found.\");\n\n                privateKey.RolloverDays = rolloverDays;\n\n                return privateKey;\n            }\n        }\n\n        public void DeletePrivateKey(ushort keyTag)\n        {","sourceCodeStart":1053,"sourceCodeEnd":1089,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimaryZone.cs#L1053-L1089","documentation":"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.","triggerScenarios":"Calling AddPrivateKey with a DnssecPrivateKey whose KeyTag matches a key already stored on the zone.","commonSituations":"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.","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."],"exampleFix":"// before\nzone.AddPrivateKey(privateKey);\n\n// after\nbool exists = zone.DnssecPrivateKeys.Any(k => k.KeyTag == privateKey.KeyTag);\nif (!exists)\n    zone.AddPrivateKey(privateKey);\nelse\n    Console.WriteLine($\"KeyTag {privateKey.KeyTag} already present; skipping.\");","handlingStrategy":"validation","validationCode":"// Ensure the incoming KeyTag is not already present\nbool exists = zone.DnssecPrivateKeys.Any(k => k.KeyTag == privateKey.KeyTag);\nif (!exists)\n    zone.AddPrivateKey(privateKey);","typeGuard":"static bool KeyTagIsFree(ApexZone zone, ushort keyTag) =>\n    !zone.DnssecPrivateKeys.Any(k => k.KeyTag == keyTag);","tryCatchPattern":"try\n{\n    zone.AddPrivateKey(privateKey);\n}\ncatch (DnsServerException ex) when (ex.Message.Contains(\"key tag collision\"))\n{\n    // delete the conflicting key or generate a fresh one instead\n}","preventionTips":["Diff the incoming keyset against zone.DnssecPrivateKeys by KeyTag before importing.","Prefer GenerateAndAddPrivateKey for net-new keys to let the server retry collisions."],"tags":["dnssec","private-key","key-tag","validation","csharp"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}