{"record":{"id":"0413ccc60f1aafb9","repo":"TechnitiumSoftware/DnsServer","slug":"cannot-update-record-use-setrecords-for-oldrec","errorCode":null,"errorMessage":"Cannot update record: use SetRecords() for {oldRecord.Type} record.","messagePattern":"Cannot update record: use SetRecords\\(\\) for (.+?) record\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimarySubDomainZone.cs","lineNumber":222,"sourceCode":"\n                        if (_primaryZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)\n                            _primaryZone.UpdateDnssecRecordsFor(this, type);\n\n                        _primaryZone.TriggerNotify();\n\n                        return true;\n                    }\n\n                    return false;\n            }\n        }\n\n        public override void UpdateRecord(DnsResourceRecord oldRecord, DnsResourceRecord newRecord)\n        {\n            switch (oldRecord.Type)\n            {\n                case DnsResourceRecordType.SOA:\n                    throw new InvalidOperationException(\"Cannot update record: use SetRecords() for \" + oldRecord.Type.ToString() + \" record.\");\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 update DNSSEC records.\");\n\n                default:\n                    if (oldRecord.Type != newRecord.Type)\n                        throw new InvalidOperationException(\"Old and new record types do not match.\");\n\n                    if ((_primaryZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned) && newRecord.GetAuthGenericRecordInfo().Disabled)\n                        throw new DnsServerException(\"Cannot update record: disabling records in a signed zones is not supported.\");\n\n                    if (newRecord.OriginalTtlValue > _primaryZone.GetZoneSoaExpire())\n                        throw new DnsServerException(\"Cannot update record: TTL cannot be greater than SOA EXPIRE.\");\n","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimarySubDomainZone.cs#L204-L240","documentation":"Thrown by PrimarySubDomainZone.UpdateRecord when the old record is of type SOA. A zone has exactly one SOA and its fields (serial, timers, nameservers) are interdependent, so the generic update-in-place path is unsafe. The guard forces callers to use SetRecords for SOA, raising InvalidOperationException before any comparison of old/new.","triggerScenarios":"zone.UpdateRecord(oldSoaRecord, newSoaRecord) where oldRecord.Type == DnsResourceRecordType.SOA. The interpolated message embeds 'SOA'.","commonSituations":"Automating SOA edits (e.g., bumping EXPIRE/refresh) via the generic update API instead of the SOA setter; UI that funnels all edits through UpdateRecord.","solutions":["Use zone.SetRecords(DnsResourceRecordType.SOA, new[] { newSoaRecord }) to replace the SOA RRset.","Adjust SOA fields through the zone's dedicated SOA helper if available.","Route SOA edits out of any generic per-record update loop."],"exampleFix":"// before\nzone.UpdateRecord(oldSoa, newSoa); // throws\n\n// after\nzone.SetRecords(DnsResourceRecordType.SOA, new[] { newSoa });","handlingStrategy":"validation","validationCode":"if (oldRecord.Type == DnsResourceRecordType.SOA)\n    zone.SetRecords(DnsResourceRecordType.SOA, new[] { newRecord });\nelse\n    zone.UpdateRecord(oldRecord, newRecord);","typeGuard":"static bool IsSingletonRecordType(DnsResourceRecordType t) => t == DnsResourceRecordType.SOA;","tryCatchPattern":null,"preventionTips":["Treat SOA as a singleton: always use SetRecords for it.","In generic update helpers, branch SOA to the setter.","Do not feed SOA rows through UpdateRecord."],"tags":["csharp","dns","soa","zone-management","validation","technitium-dns"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}