TechnitiumSoftware/DnsServer · error · ArgumentOutOfRangeException

Value cannot be less than 1.

Error message

Value cannot be less than 1.

What it means

Thrown by the MaxConcurrentResolutionsPerCore setter. This ushort property sets how many concurrent DNS resolutions may run per CPU core (it scales the resolver task pool's maximum concurrency). The only constraint is value >= 1; zero is rejected. Assigning 0 additionally triggers a resolver task pool reconfiguration guard.

Source

Thrown at DnsServerCore/Dns/DnsServer.cs:7596

        public int UdpReceiveBufferSizeKB
        {
            get { return _udpReceiveBufferSizeKB; }
            set
            {
                if ((value < 8) || (value > 65536))
                    throw new ArgumentOutOfRangeException(nameof(UdpReceiveBufferSizeKB), "Valid range is from 8 KB to 65536 KB.");

                _udpReceiveBufferSizeKB = value;
            }
        }

        public ushort MaxConcurrentResolutionsPerCore
        {
            get { return Convert.ToUInt16(_resolverTaskPool.MaximumConcurrencyLevel / Environment.ProcessorCount); }
            set
            {
                if (value < 1)
                    throw new ArgumentOutOfRangeException(nameof(MaxConcurrentResolutionsPerCore), "Value cannot be less than 1.");

                if (MaxConcurrentResolutionsPerCore != value)
                    ReconfigureResolverTaskPool(value);
            }
        }

        public bool EnableEDnsClientSubnetSourceAddress
        {
            get { return _enableEDnsClientSubnetSourceAddress; }
            set { _enableEDnsClientSubnetSourceAddress = value; }
        }

        public bool EnableDnsOverUdpProxy
        {
            get { return _enableDnsOverUdpProxy; }
            set { _enableDnsOverUdpProxy = value; }
        }

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Use a positive value (typically 2-8 per core); 1 is the minimum.
  2. Do not use 0 to disable resolution — instead stop the server or adjust upstream config.
  3. Remember the effective concurrency is value * Environment.ProcessorCount; size accordingly.
  4. When loading from config, coerce 0 to a sane default (e.g. 2) before assigning.

Example fix

// before
_dnsServer.MaxConcurrentResolutionsPerCore = 0; // throws: < 1

// after
_dnsServer.MaxConcurrentResolutionsPerCore = 4; // 4 concurrent resolutions per core
Defensive patterns

Strategy: validation

Validate before calling

ushort EnsureResolutionsPerCore(ushort value) => value < 1 ? (ushort)1 : value;

_dnsServer.MaxConcurrentResolutionsPerCore = EnsureResolutionsPerCore(parsed);

Type guard

static bool IsValidResolutionsPerCore(ushort value) => value >= 1;

Try / catch

try { _dnsServer.MaxConcurrentResolutionsPerCore = parsed; }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == nameof(DnsServer.MaxConcurrentResolutionsPerCore))
{ _dnsServer.MaxConcurrentResolutionsPerCore = 2; }

Prevention

When it happens

Trigger: Assigning DnsServer.MaxConcurrentResolutionsPerCore a value of 0 (the ushort floor). Reached from the settings API or config load. Any value >= 1 is accepted and, if changed, calls ReconfigureResolverTaskPool(value).

Common situations: Setting 0 intending 'auto' or 'disabled' — there is no auto mode; 1 is the minimum. UI input defaulting to 0 on an empty field. Misunderstanding that the value is per-core, not absolute.

Related errors


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