{"record":{"id":"5052b3269bc4415b","repo":"TechnitiumSoftware/DnsServer","slug":"cannot-delete-record-in-catalog-zone","errorCode":null,"errorMessage":"Cannot delete record in Catalog zone.","messagePattern":"Cannot delete record in Catalog zone\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/CatalogZone.cs","lineNumber":429,"sourceCode":"                    DnsResourceRecord modifiedSoaRecord = new DnsResourceRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN, 0, modifiedSoa) { Tag = newSoaRecord.Tag };\n\n                    base.SetRecords(type, [modifiedSoaRecord]);\n                    break;\n\n                default:\n                    throw new InvalidOperationException(\"Cannot set records in Catalog zone.\");\n            }\n\n        }\n\n        public override bool AddRecord(DnsResourceRecord record)\n        {\n            throw new InvalidOperationException(\"Cannot add record in Catalog zone.\");\n        }\n\n        public override bool DeleteRecords(DnsResourceRecordType type)\n        {\n            throw new InvalidOperationException(\"Cannot delete record in Catalog zone.\");\n        }\n\n        public override bool DeleteRecord(DnsResourceRecordType type, DnsResourceRecordData record)\n        {\n            throw new InvalidOperationException(\"Cannot delete records in Catalog zone.\");\n        }\n\n        public override void UpdateRecord(DnsResourceRecord oldRecord, DnsResourceRecord newRecord)\n        {\n            throw new InvalidOperationException(\"Cannot update record in Catalog zone.\");\n        }\n\n        public override IReadOnlyList<DnsResourceRecord> QueryRecords(DnsResourceRecordType type, bool dnssecOk)\n        {\n            if (type == DnsResourceRecordType.SOA)\n                return base.QueryRecords(type, dnssecOk); //allow SOA for zone transfer to work with bind\n\n            return []; //catalog zone is not queriable","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/CatalogZone.cs#L411-L447","documentation":"CatalogZone.DeleteRecords(type) unconditionally throws InvalidOperationException. Catalog zones maintain their content through automatic member zone management — the records within are derived from member zone membership. Bulk deleting records by type would corrupt the catalog's structure. Member zone removal must go through the dedicated RemoveMemberZone path.","triggerScenarios":"Calling DeleteRecords(DnsResourceRecordType) on a CatalogZone with any record type. Reached through generic zone-cleanup or record-management code that doesn't check zone type.","commonSituations":"Zone management UI/API that provides a 'delete all records of type X' button applied uniformly; cleanup scripts; zone reset operations that call DeleteRecords on all zones.","solutions":["Do not call DeleteRecords on CatalogZone — use RemoveMemberZone to manage catalog contents.","Add a zone-type check: skip DeleteRecords for CatalogZone instances.","To reset a catalog zone, delete and recreate it rather than deleting records."],"exampleFix":"// before\ncatalogZone.DeleteRecords(DnsResourceRecordType.PTR);\n// throws: Cannot delete record in Catalog zone\n\n// after\nif (zone is CatalogZone catZone)\n    catZone.RemoveMemberZone(memberName); // use catalog-specific API\nelse\n    zone.DeleteRecords(type);","handlingStrategy":"type-guard","validationCode":"if (zone is CatalogZone)\n    throw new InvalidOperationException(\"DeleteRecords is not supported on Catalog zones. Use RemoveMemberZone instead.\");\nzone.DeleteRecords(type);","typeGuard":"static bool CanDeleteRecords(Zone zone) => zone is not CatalogZone;","tryCatchPattern":null,"preventionTips":["Guard all DeleteRecords call sites with a CatalogZone type check.","Use RemoveMemberZone for catalog zone content management.","In cleanup scripts, skip catalog zones or handle them separately."],"tags":["dns","catalog-zone","rfc-9432","read-only","api-misuse"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}