{"record":{"id":"872106c1ba03efac","repo":"TechnitiumSoftware/DnsServer","slug":"cannot-publish-dnskey-no-generated-private-keys-w","errorCode":null,"errorMessage":"Cannot publish DNSKEY: no generated private keys were found.","messagePattern":"Cannot publish DNSKEY: no generated private keys were found\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimaryZone.cs","lineNumber":1130,"sourceCode":"\n            uint dnsKeyTtl = GetDnsKeyTtl();\n\n            lock (_dnssecPrivateKeys)\n            {\n                foreach (KeyValuePair<ushort, DnssecPrivateKey> privateKeyEntry in _dnssecPrivateKeys)\n                {\n                    DnssecPrivateKey privateKey = privateKeyEntry.Value;\n\n                    if (privateKey.State == DnssecPrivateKeyState.Generated)\n                    {\n                        generatedPrivateKeys.Add(privateKey);\n                        newDnsKeyRecords.Add(new DnsResourceRecord(_name, DnsResourceRecordType.DNSKEY, DnsClass.IN, dnsKeyTtl, privateKey.DnsKey));\n                    }\n                }\n            }\n\n            if (generatedPrivateKeys.Count == 0)\n                throw new DnsServerException(\"Cannot publish DNSKEY: no generated private keys were found.\");\n\n            IReadOnlyList<DnsResourceRecord> dnsKeyRecords = _entries.AddOrUpdate(DnsResourceRecordType.DNSKEY, delegate (DnsResourceRecordType key)\n            {\n                return newDnsKeyRecords;\n            },\n            delegate (DnsResourceRecordType key, IReadOnlyList<DnsResourceRecord> existingRecords)\n            {\n                foreach (DnsResourceRecord existingRecord in existingRecords)\n                {\n                    foreach (DnsResourceRecord newDnsKeyRecord in newDnsKeyRecords)\n                    {\n                        if (existingRecord.Equals(newDnsKeyRecord))\n                            throw new DnsServerException(\"Cannot publish DNSKEY: the key is already published.\");\n                    }\n                }\n\n                List<DnsResourceRecord> dnsKeyRecords = new List<DnsResourceRecord>(existingRecords.Count + newDnsKeyRecords.Count);\n","sourceCodeStart":1112,"sourceCodeEnd":1148,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimaryZone.cs#L1112-L1148","documentation":"Thrown by PublishAllGeneratedKeys when no private keys are in the Generated state. The method scans the key store for Generated keys to publish; if all keys are already Published/Ready/Active/etc., there is nothing to do and the library treats it as an error.","triggerScenarios":"Calling PublishAllGeneratedKeys when every private key on the zone has a State other than Generated.","commonSituations":"Calling publish twice in a row (the second call finds nothing Generated), or calling publish before GenerateAndAddPrivateKey has created any keys.","solutions":["Generate keys first with GenerateAndAddPrivateKey so at least one is in Generated state.","Before publishing, check whether any DnssecPrivateKeys entry has State == Generated; if none, skip the publish call.","Make publish idempotent by treating 'no Generated keys' as a no-op rather than an error."],"exampleFix":"// before\nzone.PublishAllGeneratedKeys();\n\n// after\nbool anyGenerated = zone.DnssecPrivateKeys.Any(k => k.State == DnssecPrivateKeyState.Generated);\nif (anyGenerated)\n    zone.PublishAllGeneratedKeys();","handlingStrategy":"validation","validationCode":"// Only publish when at least one Generated key exists\nbool anyGenerated = zone.DnssecPrivateKeys\n    .Any(k => k.State == DnssecPrivateKeyState.Generated);\nif (anyGenerated)\n    zone.PublishAllGeneratedKeys();","typeGuard":"static bool HasGeneratedKeys(ApexZone zone) =>\n    zone.DnssecPrivateKeys.Any(k => k.State == DnssecPrivateKeyState.Generated);","tryCatchPattern":"try\n{\n    zone.PublishAllGeneratedKeys();\n}\ncatch (DnsServerException ex) when (ex.Message.Contains(\"no generated private keys were found\"))\n{\n    // nothing to publish; treat as no-op\n}","preventionTips":["Call GenerateAndAddPrivateKey before publish so a Generated key exists.","Make publish idempotent by checking for Generated keys first."],"tags":["dnssec","private-key","dnskey","validation","type-guard","csharp"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}