{"record":{"id":"e6e1d78377ab86a4","repo":"TechnitiumSoftware/DnsServer","slug":"cannot-add-dnssec-record-e6e1d7","errorCode":null,"errorMessage":"Cannot add DNSSEC record.","messagePattern":"Cannot add DNSSEC record\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimaryZone.cs","lineNumber":2651,"sourceCode":"\n                        break;\n                }\n            }\n\n            switch (record.Type)\n            {\n                case DnsResourceRecordType.APP:\n                    throw new InvalidOperationException(\"Cannot add record: use SetRecords() for \" + record.Type.ToString() + \" record\");\n\n                case DnsResourceRecordType.DS:\n                    throw new InvalidOperationException(\"Cannot set DS record at zone apex.\");\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 add DNSSEC record.\");\n\n                case DnsResourceRecordType.FWD:\n                    throw new DnsServerException(\"The record type is not supported by primary zones.\");\n\n                default:\n                    if (record.OriginalTtlValue > GetZoneSoaExpire())\n                        throw new DnsServerException(\"Cannot add record: TTL cannot be greater than SOA EXPIRE.\");\n\n                    AddRecord(record, out IReadOnlyList<DnsResourceRecord> addedRecords, out IReadOnlyList<DnsResourceRecord> deletedRecords);\n\n                    if (addedRecords.Count > 0)\n                    {\n                        CommitAndIncrementSerial(deletedRecords, addedRecords);\n\n                        if (_dnssecStatus != AuthZoneDnssecStatus.Unsigned)\n                            UpdateDnssecRecordsFor(this, record.Type);\n\n                        TriggerNotify();","sourceCodeStart":2633,"sourceCodeEnd":2669,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimaryZone.cs#L2633-L2669","documentation":"Thrown as InvalidOperationException by PrimaryZone.AddRecord() when the record type is any DNSSEC type (DNSKEY, RRSIG, NSEC, NSEC3PARAM, NSEC3). These are generated exclusively by the signing engine; adding them manually would corrupt the signature/NSEC chain. This is a programming/usage error.","triggerScenarios":"Calling AddRecord with a record whose Type is DNSKEY, RRSIG, NSEC, NSEC3PARAM, or NSEC3 on a primary zone.","commonSituations":"Importing a signed zone's DNSSEC records via AddRecord; generic record loops that do not exclude DNSSEC types; attempting to hand-patch an RRSIG or NSEC record.","solutions":["Never AddRecord DNSSEC record types; the signing engine owns them.","Filter DNSKEY/RRSIG/NSEC/NSEC3PARAM/NSEC3 out of the record stream before AddRecord.","To produce DNSSEC records, run the DNSSEC sign/refresh flow on the zone."],"exampleFix":"// before\nforeach (var r in imported) zone.AddRecord(r); // throws on DNSSEC types\n\n// after\nforeach (var r in imported.Where(r => !IsDnssecType(r.Type)))\n    zone.AddRecord(r);","handlingStrategy":"type-guard","validationCode":"if (IsDnssecType(record.Type))\n    throw new ArgumentException($\"{record.Type} is DNSSEC-managed; use signing APIs.\");\n\nzone.AddRecord(record);\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 IsUserAddable(DnsResourceRecordType t) =>\n    t != DnsResourceRecordType.DNSKEY && t != DnsResourceRecordType.RRSIG &&\n    t != DnsResourceRecordType.NSEC && t != DnsResourceRecordType.NSEC3PARAM &&\n    t != DnsResourceRecordType.NSEC3;","tryCatchPattern":"try { zone.AddRecord(record); }\ncatch (InvalidOperationException ex) when (ex.Message == \"Cannot add DNSSEC record.\")\n{ Log.Error($\"{record.Type} is DNSSEC-managed; remove from input.\"); }","preventionTips":["Always filter DNSSEC types before AddRecord.","Let the signing engine own DNSKEY/RRSIG/NSEC records.","Treat this InvalidOperationException as a caller bug, fixed by excluding the type."],"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"}