TechnitiumSoftware/DnsServer · warning · InvalidDataException

StatCounter format is invalid.

Error message

StatCounter format is invalid.

What it means

Thrown by the StatCounter(BinaryReader) constructor when the first two ASCII bytes are not 'SC'. StatCounter is the granular stats record (per-minute, per-hour, per-day) persisted in .stat files. The 'SC' magic guards against reading a non-StatCounter or corrupt stream before the version byte is consumed.

Source

Thrown at DnsServerCore/Dns/StatsManager.cs:1870

            #endregion

            #region constructor

            public StatCounter()
            {
                _queryDomains = new ConcurrentDictionary<string, Counter>();
                _queryBlockedDomains = new ConcurrentDictionary<string, Counter>();
                _queryTypes = new ConcurrentDictionary<DnsResourceRecordType, Counter>();
                _protocolTypes = new ConcurrentDictionary<DnsTransportProtocol, Counter>();
                _clientIpAddressesUdpTcp = new ConcurrentDictionary<IPAddress, (Counter, Counter)>();
                _queries = new ConcurrentDictionary<DnsQuestionRecord, Counter>();
            }

            public StatCounter(BinaryReader bR)
            {
                if (Encoding.ASCII.GetString(bR.BaseStream.ReadExactly(2)) != "SC") //format
                    throw new InvalidDataException("StatCounter format is invalid.");

                byte version = bR.ReadByte();
                switch (version)
                {
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                        _totalQueries = bR.ReadInt32();
                        _totalNoError = bR.ReadInt32();
                        _totalServerFailure = bR.ReadInt32();
                        _totalNxDomain = bR.ReadInt32();
                        _totalRefused = bR.ReadInt32();

                        if (version >= 3)
                        {

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Delete the offending .stat file so the affected period is treated as empty.
  2. Audit the stats folder for foreign or zero-byte files and remove them.
  3. Stop the server before backing up stats to avoid capturing half-written files.
Defensive patterns

Strategy: fallback

Validate before calling

// Skip non-StatCounter files when scanning the stats folder.
Span<byte> magic = stackalloc byte[2];
if (fs.Read(magic) != 2 || magic[0] != (byte)'S' || magic[1] != (byte)'C')
    continue;

Try / catch

try { counter = new StatCounter(bR); }
catch (InvalidDataException ex) when (ex.Message == "StatCounter format is invalid.")
{ counter = new StatCounter(); }

Prevention

When it happens

Trigger: Deserializing a StatCounter from a stream whose first two bytes are not 0x53 0x43 ('SC'). Caused by a truncated/zero-byte file, corruption, a foreign file in the stats folder, or a partially-written stats file.

Common situations: Crash mid-write leaves a partial .stat; disk corruption; external tool writing into the stats folder; backup restored from a partial copy.

Related errors


AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13). Data as JSON: /api/errors/c748b502fa9baab7. Report an issue: GitHub.