{"record":{"id":"3fe395d618dea09b","repo":"TechnitiumSoftware/DnsServer","slug":"dnsserver-block-list-zone-file-format-is-invalid","errorCode":null,"errorMessage":"DnsServer block list zone file format is invalid.","messagePattern":"DnsServer block list zone file format is invalid\\.","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/ZoneManagers/BlockListZoneManager.cs","lineNumber":235,"sourceCode":"            _dnsServer.LogManager.Write(\"DNS Server block list config file was saved: \" + blockListConfigFile);\n        }\n\n        public void SaveConfigFile()\n        {\n            lock (_saveLock)\n            {\n                if (_pendingSave)\n                    return;\n\n                _pendingSave = true;\n                _saveTimer.Change(SAVE_TIMER_INITIAL_INTERVAL, Timeout.Infinite);\n            }\n        }\n\n        private void ReadConfigFrom(Stream s, bool isConfigTransfer)\n        {\n            if (Encoding.ASCII.GetString(s.ReadExactly(2)) != \"BL\") //format\n                throw new InvalidDataException(\"DnsServer block list zone file format is invalid.\");\n\n            BinaryReader bR = new BinaryReader(s);\n\n            byte version = bR.ReadByte();\n            switch (version)\n            {\n                case 1:\n                    int count = bR.ReadByte();\n                    string[] blockListUrls = new string[count];\n\n                    for (int i = 0; i < count; i++)\n                        blockListUrls[i] = s.ReadShortString();\n\n                    _blockListUpdateIntervalHours = bR.ReadInt32();\n\n                    DateTime blockListLastUpdatedOn = s.ReadDateTime();\n                    if (!isConfigTransfer)\n                        _blockListLastUpdatedOn = blockListLastUpdatedOn;","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/ZoneManagers/BlockListZoneManager.cs#L217-L253","documentation":"Thrown when loading a block-list zone config file whose first 2 bytes are not the ASCII magic 'BL'. ReadConfigFrom reads a fixed 2-byte format header before the version byte; any other content (truncated file, wrong file, text/corruption) is treated as an invalid block-list format.","triggerScenarios":"Pointing BlockListZoneManager at a non-blocklist file; a truncated or zero-length file; a file from a different feature (e.g. a 'BZ' blocked-zone file); manual edits that clobber the binary header.","commonSituations":"Backup restore put the wrong .bin into the config folder; disk corruption or partial write during a crash; upgrading across a format change where the old file is mislabeled.","solutions":["Move the offending block-list config file aside and let the server regenerate it (it recreates a valid 'BL' file on next save).","Restore the file from a known-good backup if you need the previously configured block list URLs.","Confirm only the block-list file (not a different feature's .bin) lives in the expected path."],"exampleFix":"// before: config/blockListZone.bin has wrong header -> startup of block list fails\n// after: remove so it regenerates\n//   mv config/blockListZone.bin config/blockListZone.bin.bak   (then restart server)","handlingStrategy":"validation","validationCode":"static bool IsValidBlockListFile(string path)\n{\n    using var fs = File.OpenRead(path);\n    Span<byte> hdr = stackalloc byte[2];\n    return fs.Read(hdr) == 2 && hdr[0] == (byte)'B' && hdr[1] == (byte)'L';\n}","typeGuard":null,"tryCatchPattern":"try { blockListZoneManager.Load(); }\ncatch (InvalidDataException ex) when (ex.Message.Contains(\"block list zone file format\"))\n{ File.Move(blockListPath, blockListPath + \".bad\"); blockListZoneManager.Load(); }","preventionTips":["Validate the 2-byte 'BL' header before loading.","Keep backups of feature config files separate by feature.","Let the server regenerate the file rather than hand-editing binary configs.","Stop the server cleanly so partial writes cannot truncate config files."],"tags":["dns","blocklist","config-file","serialization","startup"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}