TechnitiumSoftware/DnsServer · error · InvalidOperationException
DNS Server is already running.
Error message
DNS Server is already running.
What it means
Thrown by StartAsync when _state is not ServiceState.Stopped (i.e. already Starting, Running, or Stopping). The server is a single-instance state machine and cannot be started twice; the guard prevents overlapping listener binds.
Source
Thrown at DnsServerCore/Dns/DnsServer.cs:6637
{
if (!Socket.OSSupportsIPv6)
throw new DnsServerException(protocolName + " requires IPv6 support on the system to work.");
throw new DnsServerException(protocolName + " is supported only on Windows 11 (build 22000 and later), Windows Server 2022 (and later), and Linux. On Linux, you must install 'libmsquic' manually.");
}
}
#endregion
#region public
public async Task StartAsync(bool throwIfBindFails = false)
{
if (_disposed)
ObjectDisposedException.ThrowIf(_disposed, this);
if (_state != ServiceState.Stopped)
throw new InvalidOperationException("DNS Server is already running.");
_state = ServiceState.Starting;
//bind on all local end points
foreach (IPEndPoint localEP in _localEndPoints)
{
Socket udpListener = null;
try
{
udpListener = GetUdpListenerSocket(localEP.AddressFamily);
if ((localEP is InterfaceEndPoint intEP) && (intEP.InterfaceName is not null) && RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
try
{
udpListener.SetRawSocketOption(SOL_SOCKET, SO_BINDTODEVICE, Encoding.ASCII.GetBytes(intEP.InterfaceName));
_log.Write(localEP, DnsTransportProtocol.Udp, $"Socket was bound to device '{intEP.InterfaceName}' successfully.");View on GitHub (pinned to d0484b6c1e)
Solutions
- Call StopAsync and await it fully before calling StartAsync again.
- Guard the call: only start when State == ServiceState.Stopped.
- Serialize start/stop with a lock or a single owner to prevent concurrent transitions.
- For config changes, use the in-process reload APIs rather than stop+start.
Example fix
// before
server.StartAsync();
// ... later, without stopping:
server.StartAsync(); // throws
// after
if (server.State != ServiceState.Stopped)
await server.StopAsync();
await server.StartAsync(); Defensive patterns
Strategy: validation
Validate before calling
async Task SafeStartAsync(DnsServer server)
{
if (server.State != ServiceState.Stopped) await server.StopAsync();
await server.StartAsync();
} Type guard
static bool IsStopped(IDnsServer s) => s.State == ServiceState.Stopped;
Try / catch
try { await server.StartAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("already running")) { await server.StopAsync(); await server.StartAsync(); } Prevention
- Always fully await StopAsync before StartAsync.
- Serialize start/stop transitions with a lock.
- Use in-process reload APIs for config changes.
When it happens
Trigger: Calling StartAsync a second time while the server is running or still starting; a restart routine that calls Start without waiting for StopAsync to complete; double-invoke from a UI button race.
Common situations: Host that auto-restarts on config change without stopping first; supervisor script firing twice; the previous StopAsync is still in progress (Stopping state) when Start is invoked.
Related errors
- DHCP Server is already running.
- Zone Signing Key (ZSK) automatic rollover cannot be set sinc
- Zone Signing Key (ZSK) automatic rollover cannot be set due
- Error while creating session. Please try again.
- Failed to delete Cluster: the Cluster is not initialized.
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/6fb1ee3ccfab75d2.
Report an issue: GitHub.