TechnitiumSoftware/DnsServer · error · ArgumentOutOfRangeException

QPM Prefix Limits for IPv4 cannot have more than 255 entries

Error message

QPM Prefix Limits for IPv4 cannot have more than 255 entries.

What it means

Thrown by the QpmPrefixLimitsIPv4 property setter when the dictionary has more than 255 entries. QPM (Queries Per Minute) prefix limits map IPv4 prefix lengths to rate-limit tuples; the 255-entry cap matches byte serialization. A null value resets to an empty dictionary.

Source

Thrown at DnsServerCore/Dns/DnsServer.cs:7411

                        value = new NetworkAddress(value.Address, _eDnsClientSubnetIPv6PrefixLength);
                }

                _eDnsClientSubnetIpv6Override = value;
            }
        }

        public IReadOnlyDictionary<int, (int, int)> QpmPrefixLimitsIPv4
        {
            get { return _qpmPrefixLimitsIPv4; }
            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();
            }
        }

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Reduce the dictionary to 255 or fewer prefix-length keys (only 33 possible IPv4 prefix lengths exist: 0-32, so this is rarely hit unless duplicates are present).
  2. Check for duplicate keys being inserted under different guises.
  3. Set to null to reset if the limits are not needed.

Example fix

// before
server.QpmPrefixLimitsIPv4 = hugeRateMap; // 256+ entries

// after
server.QpmPrefixLimitsIPv4 =
    hugeRateMap.Take(32).ToDictionary(k => k.Key, v => v.Value);
Defensive patterns

Strategy: validation

Validate before calling

if (qpmV4.Count > 255)
    qpmV4 = qpmV4.Take(255).ToDictionary(k => k.Key, v => v.Value);
server.QpmPrefixLimitsIPv4 = qpmV4;

Type guard

static bool IsValidQpmDict(Dictionary<int,(int,int)> d) =>
    d is null || d.Count <= 255;

Try / catch

try { server.QpmPrefixLimitsIPv4 = qpmV4; }
catch (ArgumentOutOfRangeException) { qpmV4 = qpmV4.Take(255).ToDictionary(k=>k.Key,v=>v.Value); server.QpmPrefixLimitsIPv4 = qpmV4; }

Prevention

When it happens

Trigger: Assigning server.QpmPrefixLimitsIPv4 a dictionary with Count > 255.

Common situations: Generating prefix limits for every possible /1 through /32 as separate keys; loading a large external rate-limit config; migrating from a config that did not enforce the cap.

Related errors


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