TechnitiumSoftware/DnsServer · error · ArgumentOutOfRangeException

Network Access Control List cannot have more than 255 entrie

Error message

Network Access Control List cannot have more than 255 entries.

What it means

Thrown by the DnsReverseProxyNetworkACL setter when the supplied collection has more than byte.MaxValue (255) entries. The ACL is serialized with a single-byte length prefix (hence the 255 cap). A null or empty collection is allowed and clears the ACL; only an oversized non-empty collection throws ArgumentOutOfRangeException.

Source

Thrown at DnsServerCore/Dns/DnsServer.cs:7821

                if ((value < ushort.MinValue) || (value > ushort.MaxValue))
                    throw new ArgumentOutOfRangeException(nameof(DnsOverQuicPort), "Port number valid range is from 0 to 65535.");

                if (value == 53)
                    throw new ArgumentOutOfRangeException(nameof(DnsOverQuicPort), "Port 53 cannot be used for DNS-over-QUIC service. Please use a different port.");

                _dnsOverQuicPort = value;
            }
        }

        public IReadOnlyCollection<NetworkAccessControl> DnsReverseProxyNetworkACL
        {
            get { return _dnsReverseProxyNetworkACL; }
            set
            {
                if ((value is null) || (value.Count == 0))
                    _dnsReverseProxyNetworkACL = null;
                else if (value.Count > byte.MaxValue)
                    throw new ArgumentOutOfRangeException(nameof(DnsReverseProxyNetworkACL), "Network Access Control List cannot have more than 255 entries.");
                else
                    _dnsReverseProxyNetworkACL = value;
            }
        }

        public string DnsTlsCertificatePath
        { get { return _dnsTlsCertificatePath; } }

        public string DnsTlsCertificatePassword
        { get { return _dnsTlsCertificatePassword; } }

        public string DnsOverHttpRealIpHeader
        {
            get { return _dnsOverHttpRealIpHeader; }
            set
            {
                if (string.IsNullOrEmpty(value))
                    _dnsOverHttpRealIpHeader = "X-Real-IP";

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Reduce the ACL to at most 255 entries — aggregate narrower CIDRs into broader ranges (e.g. merge /32s into a /24).
  2. If you need more granular control, use a different filtering layer (zone ACLs, firewall rules) instead of this single-byte-indexed list.
  3. Pass null or an empty collection to clear the ACL rather than a huge dummy list.
  4. Validate Count <= 255 before assigning and trim/log the overflow entries.

Example fix

// before
_dnsServer.DnsReverseProxyNetworkACL = GeneratePerIpAcl(thousandsOfIps); // throws: > 255

// after
var acl = AggregateToCidrs(thousandsOfIps);              // merge to <= 255 CIDRs
if (acl.Count <= 255)
    _dnsServer.DnsReverseProxyNetworkACL = acl;
else
    _dnsServer.DnsReverseProxyNetworkACL = null;          // or split policy elsewhere
Defensive patterns

Strategy: validation

Validate before calling

IReadOnlyCollection<NetworkAccessControl> acl = parsedAcl;
if (acl is null || acl.Count == 0)
    _dnsServer.DnsReverseProxyNetworkACL = null;
else if (acl.Count > byte.MaxValue)
    _dnsServer.DnsReverseProxyNetworkACL = AggregateToCidrs(acl).Take(255).ToList();
else
    _dnsServer.DnsReverseProxyNetworkACL = acl;

Type guard

static bool IsValidAcl(IReadOnlyCollection<NetworkAccessControl> acl) =>
    acl is null || acl.Count == 0 || acl.Count <= byte.MaxValue;

Try / catch

try { _dnsServer.DnsReverseProxyNetworkACL = acl; }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == nameof(DnsServer.DnsReverseProxyNetworkACL))
{ _log.Warn($"ACL had {acl.Count} entries (>255); aggregating"); _dnsServer.DnsReverseProxyNetworkACL = AggregateToCidrs(acl); }

Prevention

When it happens

Trigger: Assigning DnsServer.DnsReverseProxyNetworkACL a non-empty collection with Count > 255. Reached via WebServiceSettingsApi.cs:1252/1254 settings update or DnsWebServiceLegacy.cs:518/524 ACL deserialization. Null or empty collections do NOT throw (they reset to null).

Common situations: Bulk-importing a large blocklist/CIDR list into the reverse-proxy ACL. Programmatically generating many per-client NetworkAccessControl entries and exceeding 255. Config restore from a host that had a very large ACL.

Related errors


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