TechnitiumSoftware/DnsServer · error · InvalidOperationException
Access was denied.
Error message
Access was denied.
What it means
Thrown as InvalidOperationException from DeleteGroup when the target group name (lowercased) is one of the protected built-in groups: 'everyone', 'administrators', 'dns administrators', or 'dhcp administrators'. These groups back core permission sections and cannot be removed. Returned over the API as HTTP 200 with status 'error'.
Source
Thrown at DnsServerCore/Auth/AuthManager.cs:1112
_groups.TryRemove(oldGroupName.ToLowerInvariant(), out _);
//update users
foreach (KeyValuePair<string, User> user in _users)
user.Value.RenameGroup(oldGroupName);
}
public bool DeleteGroup(string name)
{
name = name.ToLowerInvariant();
switch (name)
{
case "everyone":
case "administrators":
case "dns administrators":
case "dhcp administrators":
throw new InvalidOperationException("Access was denied.");
default:
if (_groups.TryRemove(name, out Group deletedGroup))
{
//remove all users from deleted group
foreach (KeyValuePair<string, User> user in _users)
user.Value.RemoveFromGroup(deletedGroup);
//delete all permissions
foreach (KeyValuePair<PermissionSection, Permission> permission in _permissions)
{
permission.Value.RemovePermission(deletedGroup);
permission.Value.RemoveAllSubItemPermissions(deletedGroup);
}
return true;
}
View on GitHub (pinned to d0484b6c1e)
Solutions
- Do not delete protected groups; manage access by editing their membership and permissions instead.
- Filter protected group names out of any bulk-delete loop.
- If custom role grouping is needed, create a separate group rather than reusing a built-in one.
Example fix
// before
foreach (var g in groupsToDelete)
_authManager.DeleteGroup(g); // throws on built-ins
// after
var protectedGroups = new[]{"everyone","administrators","dns administrators","dhcp administrators"};
foreach (var g in groupsToDelete.Where(n => !protectedGroups.Contains(n.ToLowerInvariant())))
_authManager.DeleteGroup(g); Defensive patterns
Strategy: validation
Validate before calling
static readonly HashSet<string> ProtectedGroups = new(StringComparer.OrdinalIgnoreCase)
{ "everyone", "administrators", "dns administrators", "dhcp administrators" };
if (ProtectedGroups.Contains(name))
throw new InvalidOperationException($"Group '{name}' is protected and cannot be deleted."); Type guard
static bool IsProtectedGroup(string name) => ProtectedGroups.Contains(name);
Try / catch
try { await client.DeleteGroupAsync(name); }
catch (HttpApiClientException ex) when (ex.Message == "Access was denied.")
{
// this is a protected built-in group; cannot be deleted
} Prevention
- Filter protected group names out of bulk-delete operations.
- Manage built-in groups via membership/permissions, not deletion.
When it happens
Trigger: POST /api/groups/delete with a name matching a protected group; attempting to remove a system group via the API or UI.
Common situations: Automation/script trying to clean up all groups indiscriminately; an admin attempting to delete a built-in role group.
Related errors
- Cannot create more than 255 groups.
- Group already exists: {name}
- Group already exists: {newGroupName}
- Access was denied.
- Access was denied.
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/3dc1475acdfb4d70.
Report an issue: GitHub.