{"record":{"id":"18dc4620bdc7960e","repo":"TechnitiumSoftware/DnsServer","slug":"cannot-set-dnssec-records-18dc46","errorCode":null,"errorMessage":"Cannot set DNSSEC records.","messagePattern":"Cannot set DNSSEC records\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimaryZone.cs","lineNumber":2598,"sourceCode":"                            case AuthZoneDnssecStatus.SignedWithNSEC:\n                                RefreshNSec();\n                                break;\n\n                            case AuthZoneDnssecStatus.SignedWithNSEC3:\n                                RefreshNSec3();\n                                break;\n                        }\n                    }\n\n                    TriggerNotify();\n                    break;\n\n                case DnsResourceRecordType.DNSKEY:\n                case DnsResourceRecordType.RRSIG:\n                case DnsResourceRecordType.NSEC:\n                case DnsResourceRecordType.NSEC3PARAM:\n                case DnsResourceRecordType.NSEC3:\n                    throw new InvalidOperationException(\"Cannot set DNSSEC records.\");\n\n                case DnsResourceRecordType.FWD:\n                    throw new DnsServerException(\"The record type is not supported by primary zones.\");\n\n                default:\n                    if (records[0].OriginalTtlValue > GetZoneSoaExpire())\n                        throw new DnsServerException(\"Cannot set records: TTL cannot be greater than SOA EXPIRE.\");\n\n                    if (!TrySetRecords(type, records, out IReadOnlyList<DnsResourceRecord> deletedRecords))\n                        throw new DnsServerException(\"Cannot set records. Please try again.\");\n\n                    CommitAndIncrementSerial(deletedRecords, records);\n\n                    if (_dnssecStatus != AuthZoneDnssecStatus.Unsigned)\n                        UpdateDnssecRecordsFor(this, type);\n\n                    TriggerNotify();\n                    break;","sourceCodeStart":2580,"sourceCodeEnd":2616,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimaryZone.cs#L2580-L2616","documentation":"Thrown as InvalidOperationException by PrimaryZone.SetRecords() when the requested type is any DNSSEC record type (DNSKEY, RRSIG, NSEC, NSEC3PARAM, NSEC3). These records are generated and maintained exclusively by the DNSSEC signing engine; setting them manually would corrupt the signature chain. This is a programming/usage error.","triggerScenarios":"Calling SetRecords with DnsResourceRecordType.DNSKEY, RRSIG, NSEC, NSEC3PARAM, or NSEC3 on a primary zone.","commonSituations":"Bulk record-import tooling that does not exclude DNSSEC types; attempting to hand-edit signatures or NSEC chains; copy-pasting a signed zone's DNSSEC records into SetRecords on another zone.","solutions":["Never call SetRecords with DNSSEC record types; let the signing engine produce them via the DNSSEC sign/refresh APIs.","Filter DNSKEY/RRSIG/NSEC/NSEC3PARAM/NSEC3 out of any record set before calling SetRecords.","To change DNSKEY TTL use UpdateDnsKeyTtl; to (re)sign the zone use the DNSSEC signing flow."],"exampleFix":"// before\nzone.SetRecords(type, records); // throws for DNSSEC types\n\n// after\nvar userManaged = records.Where(r => !IsDnssecType(r.Type)).ToList();\nzone.SetRecords(type, userManaged);\n// bool IsDnssecType(DnsResourceRecordType t) => t == DNSKEY || t == RRSIG || t == NSEC || t == NSEC3PARAM || t == NSEC3;","handlingStrategy":"type-guard","validationCode":"if (IsDnssecType(type))\n    throw new ArgumentException($\"{type} is managed by the DNSSEC engine; use signing APIs.\");\n\nzone.SetRecords(type, records);\n// static bool IsDnssecType(DnsResourceRecordType t) =>\n//     t == DnsResourceRecordType.DNSKEY || t == DnsResourceRecordType.RRSIG ||\n//     t == DnsResourceRecordType.NSEC || t == DnsResourceRecordType.NSEC3PARAM ||\n//     t == DnsResourceRecordType.NSEC3;","typeGuard":"static bool IsUserSettable(DnsResourceRecordType t) =>\n    t != DnsResourceRecordType.DNSKEY && t != DnsResourceRecordType.RRSIG &&\n    t != DnsResourceRecordType.NSEC && t != DnsResourceRecordType.NSEC3PARAM &&\n    t != DnsResourceRecordType.NSEC3;","tryCatchPattern":"try { zone.SetRecords(type, records); }\ncatch (InvalidOperationException ex) when (ex.Message == \"Cannot set DNSSEC records.\")\n{ Log.Error($\"{type} is DNSSEC-managed; remove from input.\"); }","preventionTips":["Always filter DNSSEC types out of record sets before SetRecords.","Use UpdateDnsKeyTtl and the signing APIs for DNSSEC records.","Treat InvalidOperationException here as a caller bug to fix, not catch in production."],"tags":["dns","dnssec","record","rrsig","nsec","dnskey","invalidoperation","validation"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}