TechnitiumSoftware/DnsServer · error · DnsWebServiceException

Max limit of {MAX_LOGIN_ATTEMPTS} attempts exceeded. Access

Error message

Max limit of {MAX_LOGIN_ATTEMPTS} attempts exceeded. Access blocked for {BLOCK_NETWORK_INTERVAL / 1000} seconds.

What it means

Thrown as DnsWebServiceException from AuthenticateUserAsync when IsNetworkBlocked returns true for the client's /32 (IPv4) or /128 (IPv6) network. After 5 failed logins (MAX_LOGIN_ATTEMPTS) the source network is blocked for 300 seconds (BLOCK_NETWORK_INTERVAL = 5*60*1000 ms). The message interpolates both constants so it reads '...5 attempts...300 seconds.' It is returned over the API as HTTP 200 with status 'error'.

Source

Thrown at DnsServerCore/Auth/AuthManager.cs:786

                    _log.Write(ex);

                    adminUser = CreateUser("Administrator", "admin", "admin");
                }
            }
            else
            {
                adminUser = CreateUser("Administrator", "admin", "admin");
            }

            adminUser.AddToGroup(adminGroup);
        }

        private async Task<User> AuthenticateUserAsync(string username, string password, string totp, IPAddress remoteAddress)
        {
            IPAddress network = GetClientNetwork(remoteAddress);

            if (IsNetworkBlocked(network))
                throw new DnsWebServiceException("Max limit of " + MAX_LOGIN_ATTEMPTS + " attempts exceeded. Access blocked for " + (BLOCK_NETWORK_INTERVAL / 1000) + " seconds.");

            User user = GetUser(username);

            if ((user is null) || user.IsSsoUser || !user.PasswordHash.Equals(user.GetPasswordHashFor(password), StringComparison.Ordinal))
            {
                if ((username != "admin") || (password != "admin"))
                {
                    MarkFailedLoginAttempt(network);

                    if (HasLoginAttemptExceedLimit(network, MAX_LOGIN_ATTEMPTS))
                        BlockNetwork(network, BLOCK_NETWORK_INTERVAL);
                }

                await Task.Delay(1000);

                throw new DnsWebServiceException("Invalid username or password for user: " + username);
            }

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Wait 300 seconds (5 minutes) for the block to expire, then retry with correct credentials.
  2. Log in from a different source IP/network that is not blocked.
  3. Have an admin remove the block by restarting the service (blocks are in-memory) or correcting the credentials of the failing automation immediately.
  4. Fix the automation/monitor that is generating the failed attempts so it stops re-triggering the block.
Defensive patterns

Strategy: retry

Validate before calling

// No pre-call API to read block state; the only 'validation' is honoring the backoff.
// Do not hammer login; back off for 300s after repeated failures.

Try / catch

// In HttpApiClient-style code:
try { await client.LoginAsync(user, pass); }
catch (HttpApiClientException ex) when (ex.Message.Contains("Access blocked"))
{
    await Task.Delay(TimeSpan.FromSeconds(310)); // BLOCK_NETWORK_INTERVAL (300s) + margin
    await client.LoginAsync(user, pass);
}

Prevention

When it happens

Trigger: Any login attempt (POST /api/user/login) from an IP whose network is in _blockedNetworks because it previously hit 5 failed attempts. The check happens before credential validation, so even a correct password is rejected while the block is active.

Common situations: An admin fat-fingered the password 5 times; an automated script/monitor retries bad credentials; a NAT/shared IP aggregates many clients so one client's failures block all; the 300s window has not elapsed yet.

Related errors


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