{"record":{"id":"9ce3a2bd052d4fde","repo":"TechnitiumSoftware/DnsServer","slug":"cannot-set-ds-record-at-zone-apex","errorCode":null,"errorMessage":"Cannot set DS record at zone apex.","messagePattern":"Cannot set DS record at zone apex\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimaryZone.cs","lineNumber":2644,"sourceCode":"                    case DnsResourceRecordType.ANAME:\n                    case DnsResourceRecordType.APP:\n                        throw new DnsServerException(\"The record type is not supported by DNSSEC signed primary zones.\");\n\n                    default:\n                        if (record.GetAuthGenericRecordInfo().Disabled)\n                            throw new DnsServerException(\"Cannot add record: disabling records in a signed zones is not supported.\");\n\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)","sourceCodeStart":2626,"sourceCodeEnd":2662,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimaryZone.cs#L2626-L2662","documentation":"Thrown as InvalidOperationException by PrimaryZone.AddRecord() when the record type is DS. A DS record at the zone apex is not added locally; it is published in the parent zone to establish the chain of trust. AddRecord therefore refuses DS on a primary (apex) zone. This is a programming/usage error.","triggerScenarios":"Calling AddRecord with a record whose Type is DnsResourceRecordType.DS on a primary zone.","commonSituations":"Automation that adds DS records to the child zone instead of the parent; importing a zone bundle that includes parent-side DS records.","solutions":["Do not add DS records to the child (primary) zone; publish the DS in the parent zone instead.","Use the DNSSEC parent-zone DS management API to install the DS for chain-of-trust.","Filter DS out of any AddRecord input on a primary zone."],"exampleFix":"// before\nzone.AddRecord(dsRecord); // throws: DS goes in parent zone\n\n// after\nparentZone.AddRecord(dsRecord); // install DS in the parent zone","handlingStrategy":"type-guard","validationCode":"if (record.Type == DnsResourceRecordType.DS)\n    throw new ArgumentException(\"DS records are published in the parent zone, not added here.\");\n\nzone.AddRecord(record);","typeGuard":"static bool IsAddableAtApex(DnsResourceRecordType t) =>\n    t != DnsResourceRecordType.DS;","tryCatchPattern":"try { zone.AddRecord(record); }\ncatch (InvalidOperationException ex) when (ex.Message == \"Cannot set DS record at zone apex.\")\n{ Log.Error(\"Add DS to the parent zone instead.\"); }","preventionTips":["Publish DS in the parent zone via its DS management API.","Filter DS from child-zone AddRecord input.","Model chain-of-trust records separately from zone content."],"tags":["dns","dnssec","record","ds","apex","invalidoperation","validation"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}