TechnitiumSoftware/DnsServer · error · ArgumentOutOfRangeException

QPM limit value cannot be less than 0.

Error message

QPM limit value cannot be less than 0.

What it means

Thrown by the QpmPrefixLimitsIPv4 property setter when any tuple value has Item1 (queries) or Item2 (limit) below 0. QPM limit values represent query counts and must be non-negative.

Source

Thrown at DnsServerCore/Dns/DnsServer.cs:7421

            set
            {
                if (value is null)
                {
                    _qpmPrefixLimitsIPv4 = new Dictionary<int, (int, int)>();
                }
                else if (value.Count > byte.MaxValue)
                {
                    throw new ArgumentOutOfRangeException(nameof(QpmPrefixLimitsIPv4), "QPM Prefix Limits for IPv4 cannot have more than 255 entries.");
                }
                else
                {
                    foreach (KeyValuePair<int, (int, int)> qpmPrefixLimit in value)
                    {
                        if ((qpmPrefixLimit.Key < 0) || (qpmPrefixLimit.Key > 32))
                            throw new ArgumentOutOfRangeException(nameof(QpmPrefixLimitsIPv4), "QPM limit IPv4 prefix valid range is between 0 and 32.");

                        if ((qpmPrefixLimit.Value.Item1 < 0) || (qpmPrefixLimit.Value.Item2 < 0))
                            throw new ArgumentOutOfRangeException(nameof(QpmPrefixLimitsIPv4), "QPM limit value cannot be less than 0.");
                    }

                    _qpmPrefixLimitsIPv4 = value;
                }

                ResetQpsLimitTimer();
            }
        }

        public IReadOnlyDictionary<int, (int, int)> QpmPrefixLimitsIPv6
        {
            get { return _qpmPrefixLimitsIPv6; }
            set
            {
                if (value is null)
                {
                    _qpmPrefixLimitsIPv6 = new Dictionary<int, (int, int)>();
                }

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Ensure all QPM limit tuple values are >= 0.
  2. Clamp computed values with Math.Max(0, value) before building the dictionary.

Example fix

// before
server.QpmPrefixLimitsIPv4 =
    new Dictionary<int,(int,int)> { { 24, (-5, 100) } }; // throws

// after
server.QpmPrefixLimitsIPv4 =
    new Dictionary<int,(int,int)> { { 24, (5, 100) } };
Defensive patterns

Strategy: validation

Validate before calling

foreach (var kv in qpmV4)
    if (kv.Value.Item1 < 0 || kv.Value.Item2 < 0)
        throw new InvalidOperationException($"Negative QPM value for prefix {kv.Key}");
server.QpmPrefixLimitsIPv4 = qpmV4;

Type guard

static bool IsValidQpmValue((int,int) v) => v.Item1 >= 0 && v.Item2 >= 0;

Try / catch

try { server.QpmPrefixLimitsIPv4 = qpmV4; }
catch (ArgumentOutOfRangeException) { qpmV4 = qpmV4.Select(kv => (kv.Key, (Math.Max(0,kv.Value.Item1), Math.Max(0,kv.Value.Item2)))).ToDictionary(x=>x.Key,x=>x.Item2); server.QpmPrefixLimitsIPv4 = qpmV4; }

Prevention

When it happens

Trigger: Assigning QpmPrefixLimitsIPv4 a dictionary where any value tuple has a negative Item1 or Item2.

Common situations: Arithmetic producing a negative value when computing limits from a baseline; config file with a typo (e.g. negative number); default/uninitialized integer fields passed through.

Related errors


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