TechnitiumSoftware/DnsServer · error · DnsWebServiceException

Invalid username or password for user: {username}

Error message

Invalid username or password for user: {username}

What it means

Thrown as DnsWebServiceException after a 1-second delay when the user is null, is an SSO-only user, or the supplied password hash does not match. It intentionally does not distinguish 'no such user' from 'wrong password' to avoid user enumeration, and it logs a failed attempt toward the network block. Returned over the API as HTTP 200 with status 'error'.

Source

Thrown at DnsServerCore/Auth/AuthManager.cs:802

            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);
            }

            if (user.TOTPEnabled)
            {
                if (string.IsNullOrEmpty(totp))
                    throw new TwoFactorAuthRequiredWebServiceException("A time-based one-time password (TOTP) is required for user: " + username);

                Authenticator authenticator = new Authenticator(user.TOTPKeyUri);

                if (!authenticator.IsTOTPValid(totp))
                {
                    MarkFailedLoginAttempt(network);

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

                    await Task.Delay(1000);

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Correct the username/password (check for trailing spaces and case of the password).
  2. If the account is SSO-only, authenticate via the SSO/OIDC flow instead of local password.
  3. Reset the password using resetadmin.config or have an admin reset it.
  4. Confirm the user still exists and is spelled exactly (usernames are lowercased on creation).
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate inputs client-side before calling login
if (string.IsNullOrWhiteSpace(user) || string.IsNullOrWhiteSpace(pass))
    throw new ArgumentException("Username and password are required.");

Try / catch

try { await client.LoginAsync(user, pass, totp); }
catch (HttpApiClientException ex) when (ex.Message.StartsWith("Invalid username or password"))
{
    // show generic error; do NOT distinguish no-user vs wrong-password
    ShowLoginFailed();
}

Prevention

When it happens

Trigger: POST /api/user/login (or changePassword) where the user does not exist, the password is wrong, or the account is SSO-only (local password login is rejected for IsSsoUser users). Note: the literal 'admin'/'admin' default bypasses the failed-attempt counter.

Common situations: Wrong password typed; password was changed by an admin; user was deleted or renamed; trying password login for an account created via SSO that has no local password; copy-paste of credentials with trailing whitespace.

Related errors


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