{"record":{"id":"f0ce8c6324eff923","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-set-dnssec-records-please-try-again","errorCode":null,"errorMessage":"Failed to set DNSSEC records. Please try again.","messagePattern":"Failed to set DNSSEC records\\. Please try again\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimaryZone.cs","lineNumber":834,"sourceCode":"            List<DnsResourceRecord> deletedRecords = new List<DnsResourceRecord>();\n\n            uint ttl = GetZoneSoaMinimum();\n\n            for (int i = 0; i < zones.Count; i++)\n            {\n                AuthZone zone = zones[i];\n                AuthZone nextZone;\n\n                if (i < zones.Count - 1)\n                    nextZone = zones[i + 1];\n                else\n                    nextZone = zones[0];\n\n                IReadOnlyList<DnsResourceRecord> newNSecRecords = zone.GetUpdatedNSecRRSet(nextZone.Name, ttl);\n                if (newNSecRecords.Count > 0)\n                {\n                    if (!zone.TrySetRecords(DnsResourceRecordType.NSEC, newNSecRecords, out IReadOnlyList<DnsResourceRecord> deletedNSecRecords))\n                        throw new DnsServerException(\"Failed to set DNSSEC records. Please try again.\");\n\n                    addedRecords.AddRange(newNSecRecords);\n                    deletedRecords.AddRange(deletedNSecRecords);\n\n                    IReadOnlyList<DnsResourceRecord> newRRSigRecords = SignRRSet(newNSecRecords);\n                    if (newRRSigRecords.Count > 0)\n                    {\n                        zone.AddOrUpdateRRSigRecords(newRRSigRecords, out IReadOnlyList<DnsResourceRecord> deletedRRSigRecords);\n\n                        addedRecords.AddRange(newRRSigRecords);\n                        deletedRecords.AddRange(deletedRRSigRecords);\n                    }\n                }\n            }\n\n            CommitAndIncrementSerial(deletedRecords, addedRecords);\n        }\n","sourceCodeStart":816,"sourceCodeEnd":852,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimaryZone.cs#L816-L852","documentation":"Thrown by the private EnableNSec helper when zone.TrySetRecords for the NSEC RRset returns false during signing or NSEC re-enabling. The false result means the zone could not atomically commit the freshly computed NSEC records (typically a concurrent write or an integrity check inside the zone), so the library aborts with a 'please try again' message.","triggerScenarios":"Triggered indirectly during SignZone, ConvertToNSec3, ConvertToNSec, or RefreshNSec when TrySetRecords(NSEC, ...) fails internally for a given zone.","commonSituations":"High concurrency: another thread is mutating the same zone records while a DNSSEC operation is mid-flight, or a transient inconsistency between the computed NSEC RRset and the zone's current state.","solutions":["Retry the signing or conversion operation; the failure path is designed to be transient.","Ensure no other code path is concurrently adding/removing records in the same zone during the DNSSEC operation.","If it persists, dump the zone's current NSEC records for the failing owner name and check for corruption."],"exampleFix":"// before\nzone.SignZone(keys, dnsKeyTtl, useNSec3: false);\n\n// after\nfor (int attempt = 0; attempt < 3; attempt++)\n{\n    try\n    {\n        zone.SignZone(keys, dnsKeyTtl, useNSec3: false);\n        break;\n    }\n    catch (DnsServerException ex) when (ex.Message.Contains(\"Failed to set DNSSEC records\"))\n    {\n        if (attempt == 2) throw;\n    }\n}","handlingStrategy":"retry","validationCode":"// No pure pre-check exists; this is a transient commit failure.\n// Best pre-check: avoid concurrent record mutations on the same zone.\nusing (await zoneLock.LockAsync())\n{\n    zone.SignZone(keys, dnsKeyTtl, useNSec3: false);\n}","typeGuard":null,"tryCatchPattern":"for (int attempt = 0; attempt < 3; attempt++)\n{\n    try\n    {\n        zone.SignZone(keys, dnsKeyTtl, useNSec3: false);\n        break;\n    }\n    catch (DnsServerException ex) when (ex.Message.Contains(\"Failed to set DNSSEC records\"))\n    {\n        if (attempt == 2) throw;\n    }\n}","preventionTips":["Serialize DNSSEC operations on a single zone behind a lock to avoid concurrent TrySetRecords contention.","Treat 'Failed to set DNSSEC records' as transient and retry a bounded number of times."],"tags":["dnssec","nsec","concurrency","retry","internal"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}