TechnitiumSoftware/DnsServer · error · DnsWebServiceException
User already exists: {newUsername}
Error message
User already exists: {newUsername} What it means
Thrown as DnsWebServiceException from ChangeUsername when TryAdd of the new username fails because that name is already taken. The username is reverted to the old value before throwing, leaving state consistent. Returned over the API as HTTP 200 with status 'error'.
Source
Thrown at DnsServerCore/Auth/AuthManager.cs:986
public bool HasDefaultCredentials()
{
User user = GetUser("admin");
return (user is not null) && user.PasswordHash.Equals(user.GetPasswordHashFor("admin"), StringComparison.Ordinal);
}
public void ChangeUsername(User user, string newUsername)
{
if (user.Username.Equals(newUsername, StringComparison.OrdinalIgnoreCase))
return;
string oldUsername = user.Username;
user.SetUsername(newUsername);
if (!_users.TryAdd(user.Username, user))
{
user.SetUsername(oldUsername); //revert
throw new DnsWebServiceException("User already exists: " + newUsername);
}
_users.TryRemove(oldUsername, out _);
}
public async Task<User> ChangePasswordAsync(string username, string password, string totp, IPAddress remoteAddress, string newPassword, int iterations)
{
User user = await AuthenticateUserAsync(username, password, totp, remoteAddress);
user.ChangePassword(newPassword, iterations);
return user;
}
public bool DeleteUser(string username)
{
if (_users.TryRemove(username.ToLowerInvariant(), out User deletedUser))
{View on GitHub (pinned to d0484b6c1e)
Solutions
- Choose a username that does not exist (check case-insensitively).
- Delete or rename the conflicting user first.
- Verify the target name via GetUser before attempting the rename.
Example fix
// before
_authManager.ChangeUsername(user, newUsername);
// after
if (GetUser(newUsername) is null)
_authManager.ChangeUsername(user, newUsername); Defensive patterns
Strategy: validation
Validate before calling
if (await GetUserAsync(newUsername) is not null)
throw new InvalidOperationException($"Username '{newUsername}' is taken."); Try / catch
try { await client.ChangeUsernameAsync(user, newUsername); }
catch (HttpApiClientException ex) when (ex.Message.StartsWith("User already exists"))
{
PromptForDifferentUsername();
} Prevention
- Check the target username case-insensitively before renaming.
- Delete or rename conflicting users first.
When it happens
Trigger: POST /api/users/changeUsername (or equivalent) targeting a newUsername that already exists as a (lowercased) key; a no-op fast path exists only if the new name equals the current name case-insensitively.
Common situations: Renaming a user to a name that collides with another active or local user; case-only target that differs from current only by case still triggers the collision because keys are lowercased and equality is OrdinalIgnoreCase on the fast path.
Related errors
- User already exists: {username}
- User account is disabled. Please contact your administrator.
- Cannot create more than 255 users.
- Group already exists: {name}
- Group already exists: {newGroupName}
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/3e75a70b0b456f7f.
Report an issue: GitHub.