{"record":{"id":"de477baf7c1e88c4","repo":"TechnitiumSoftware/DnsServer","slug":"cannot-add-record-use-setrecords-for-type-rec","errorCode":null,"errorMessage":"Cannot add record: use SetRecords() for {type} record.","messagePattern":"Cannot add record: use SetRecords\\(\\) for (.+?) record\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/AuthZone.cs","lineNumber":312,"sourceCode":"                }\n\n                updatedRecords.AddRange(newRRSigRecords);\n\n                deleted = deletedRecords;\n                return updatedRecords;\n            });\n\n            deletedRRSigRecords = deleted;\n        }\n\n        internal void AddRecord(DnsResourceRecord record, out IReadOnlyList<DnsResourceRecord> addedRecords, out IReadOnlyList<DnsResourceRecord> deletedRecords)\n        {\n            switch (record.Type)\n            {\n                case DnsResourceRecordType.CNAME:\n                case DnsResourceRecordType.DNAME:\n                case DnsResourceRecordType.SOA:\n                    throw new InvalidOperationException(\"Cannot add record: use SetRecords() for \" + record.Type.ToString() + \" record.\");\n\n                default:\n                    if (_entries.ContainsKey(DnsResourceRecordType.CNAME))\n                        throw new InvalidOperationException(\"Cannot add record: a CNAME record cannot exists with other record types for the same name.\");\n\n                    break;\n            }\n\n            List<DnsResourceRecord> added = new List<DnsResourceRecord>();\n            List<DnsResourceRecord> deleted = new List<DnsResourceRecord>();\n\n            addedRecords = added;\n            deletedRecords = deleted;\n\n            _entries.AddOrUpdate(record.Type, delegate (DnsResourceRecordType key)\n            {\n                added.Add(record);\n                return [record];","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/AuthZone.cs#L294-L330","documentation":"AuthZone.AddRecord explicitly rejects CNAME, DNAME, and SOA record types with InvalidOperationException. These types are singleton-per-name records with special semantics: SOA is the zone's Start of Authority (one per zone), and CNAME/DNAME are exclusive types that cannot coexist with others. The library requires you to use SetRecords() instead, which performs the proper validation and atomic replacement logic for these singleton types.","triggerScenarios":"Calling the internal AddRecord method (or the public AddRecord wrapper) with a DnsResourceRecord whose Type is CNAME, DNAME, or SOA. This happens when application code uses AddRecord for a record type that must be managed exclusively via SetRecords.","commonSituations":"Programmatic zone management code that treats all record types uniformly through AddRecord; migration scripts that add records in a loop without type-specific routing; web API handlers that incorrectly route SOA/CNAME/DNAME modifications through AddRecord.","solutions":["Use SetRecords(type, [record]) for CNAME, DNAME, and SOA records instead of AddRecord(record).","Add a type check in calling code: if the record type is CNAME/DNAME/SOA, route to SetRecords; otherwise use AddRecord.","For SOA modifications specifically, use the zone's dedicated SOA management methods (e.g., increment serial via the zone's built-in mechanism)."],"exampleFix":"// before\nzone.AddRecord(new DnsResourceRecord(name, DnsResourceRecordType.SOA, ...));\n// throws: use SetRecords() for SOA record\n\n// after\nzone.SetRecords(DnsResourceRecordType.SOA, new[] { soaRecord });","handlingStrategy":"type-guard","validationCode":"static bool RequiresSetRecords(DnsResourceRecordType type)\n    => type == DnsResourceRecordType.CNAME\n    || type == DnsResourceRecordType.DNAME\n    || type == DnsResourceRecordType.SOA;\n\nif (RequiresSetRecords(record.Type))\n    zone.SetRecords(record.Type, new[] { record });\nelse\n    zone.AddRecord(record);","typeGuard":"static bool CanAddRecord(DnsResourceRecordType type)\n    => type != DnsResourceRecordType.CNAME\n    && type != DnsResourceRecordType.DNAME\n    && type != DnsResourceRecordType.SOA;","tryCatchPattern":null,"preventionTips":["Route CNAME, DNAME, and SOA through SetRecords in all record-management code.","Build a type-dispatch helper that automatically selects AddRecord vs SetRecords.","Document the singleton-type restriction in API handler code."],"tags":["dns","record-management","singleton-record","auth-zone","api-misuse"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}