{"record":{"id":"080514dc1803ca92","repo":"TechnitiumSoftware/DnsServer","slug":"zone-does-not-contain-soa-record","errorCode":null,"errorMessage":"Zone does not contain SOA record.","messagePattern":"Zone does not contain SOA record\\.","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/ZoneManagers/AuthZoneManager.cs","lineNumber":444,"sourceCode":"                    }\n                    break;\n            }\n        }\n\n        public AuthZoneInfo LoadZoneFrom(Stream s, DateTime lastModified)\n        {\n            if (Encoding.ASCII.GetString(s.ReadExactly(2)) != \"DZ\")\n                throw new InvalidDataException(\"DnsServer zone file format is invalid.\");\n\n            BinaryReader bR = new BinaryReader(s);\n\n            switch (bR.ReadByte())\n            {\n                case 2:\n                    {\n                        DnsResourceRecord[] records = new DnsResourceRecord[bR.ReadInt32()];\n                        if (records.Length == 0)\n                            throw new InvalidDataException(\"Zone does not contain SOA record.\");\n\n                        DnsResourceRecord soaRecord = null;\n\n                        for (int i = 0; i < records.Length; i++)\n                        {\n                            records[i] = new DnsResourceRecord(s);\n\n                            if (records[i].Type == DnsResourceRecordType.SOA)\n                                soaRecord = records[i];\n                        }\n\n                        if (soaRecord == null)\n                            throw new InvalidDataException(\"Zone does not contain SOA record.\");\n\n                        //make zone info\n                        AuthZoneType zoneType;\n                        if (_dnsServer.ServerDomain.Equals((soaRecord.RDATA as DnsSOARecordData).PrimaryNameServer, StringComparison.OrdinalIgnoreCase))\n                            zoneType = AuthZoneType.Primary;","sourceCodeStart":426,"sourceCodeEnd":462,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/ZoneManagers/AuthZoneManager.cs#L426-L462","documentation":"Thrown by AuthZoneManager.LoadZoneFrom in zone-file version 2 when the record count read from the stream is 0. Every DNS zone must contain at least a Start of Authority (SOA) record, so a zero-count record list is invalid before any record is even parsed.","triggerScenarios":"Loading a version-2 zone file whose 4-byte record-count integer is 0 — the file was written empty or its header is corrupt.","commonSituations":"An empty zone file produced by a failed/cancelled save, a corrupt count field from a partial write, or a hand-crafted/edited binary zone missing its records.","solutions":["Restore the zone from a backup that contains records, or delete and re-create the zone (primary) or re-transfer (secondary).","Ensure the zone is never persisted with a zero record count — guard the writer or use atomic temp-file + rename.","Validate the zone file (record count > 0) before trusting it."],"exampleFix":"// before\nzoneManager.LoadZoneFrom(fs, lastModified); // count==0 throws\n\n// after\nusing var br = new BinaryReader(fs);\nif (Encoding.ASCII.GetString(br.ReadBytes(2)) != \"DZ\") throw new InvalidDataException(\"bad magic\");\nif (br.ReadByte() != 2) throw new InvalidDataException(\"unsupported version\");\nint count = br.ReadInt32();\nif (count == 0) { /* skip / restore backup */ return; }\nfs.Position = 0;\nzoneManager.LoadZoneFrom(fs, lastModified);","handlingStrategy":"validation","validationCode":"int ZoneV2RecordCount(string path)\n{\n    using var fs = File.OpenRead(path);\n    using var br = new BinaryReader(fs);\n    if (Encoding.ASCII.GetString(br.ReadBytes(2)) != \"DZ\") return -1;\n    if (br.ReadByte() != 2) return -1;\n    return br.ReadInt32();\n}","typeGuard":null,"tryCatchPattern":"try { zoneManager.LoadZoneFrom(fs, lastModified); }\ncatch (InvalidDataException ex) when (ex.Message == \"Zone does not contain SOA record.\")\n{\n    // empty zone file — restore from backup or re-create/re-transfer\n}","preventionTips":["Never persist a zone with zero records.","Validate the record count > 0 before loading.","Back up zone files and write them atomically."],"tags":["dns","csharp","zone-file","soa","validation","technitium"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}