denoland/deno · error · Error

ERR_SOCKET_DGRAM_NOT_RUNNING

ERR_SOCKET_DGRAM_NOT_RUNNING

Error message

Not running

What it means

healthCheck() runs before dgram socket operations (addMembership, dropMembership, setMulticastInterface, setTTL-family calls, the send path, etc.) and throws ERR_SOCKET_DGRAM_NOT_RUNNING when the internal handle is null — i.e. the socket is not bound/running (no bind() yet) or has already been closed. The message mirrors Node's classic dgram 'Not running' error.

Source

Thrown at ext/node/polyfills/dgram.ts:1423

  const ctx = {};
  const ret = self[kStateSymbol].handle!.bufferSize(size, buffer, ctx);

  if (ret === undefined) {
    throw new ERR_SOCKET_BUFFER_SIZE(ctx as NodeSystemErrorCtx);
  }

  return ret;
}

function socketCloseNT(self: Socket) {
  self.emit("close");
}

function healthCheck(socket: Socket) {
  if (!socket[kStateSymbol].handle) {
    // Error message from dgram_legacy.js.
    throw new ERR_SOCKET_DGRAM_NOT_RUNNING();
  }
}

function stopReceiving(socket: Socket) {
  const state = socket[kStateSymbol];

  if (!state.receiving) {
    return;
  }

  state.handle!.recvStop();
  state.receiving = false;
}

function onMessage(
  nread: number,
  handle: UDP,
  buf?: Buffer,

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. bind the socket first and do multicast/TTL configuration inside the 'listening' event callback
  2. Guard shutdown paths: set a closed flag in the 'close' handler and skip socket calls after it
  3. Re-create the socket (and re-bind) instead of reusing a closed one

Example fix

// before
const sock = dgram.createSocket('udp4');
sock.addMembership('224.0.0.114'); // throws ERR_SOCKET_DGRAM_NOT_RUNNING: not bound yet

// after
const sock = dgram.createSocket('udp4');
sock.bind(0, () => {
  sock.addMembership('224.0.0.114');
});
Defensive patterns

Strategy: validation

Validate before calling

let running = false;
sock.on('listening', () => { running = true; });
sock.on('close', () => { running = false; });
function safely(fn, ...args) {
  if (!running) return; // skip addMembership/setTTL/etc. when not bound or closed
  fn.apply(sock, args);
}

Type guard

const isRunning = (s) => s != null && s._handle !== null && !s.closed; // heuristic; prefer tracking 'listening'/'close'

Try / catch

catch (e) { if (e?.code === 'ERR_SOCKET_DGRAM_NOT_RUNNING') return; /* socket gone: no-op */ throw e; }

Prevention

When it happens

Trigger: Calling socket.addMembership('224.0.0.114') before socket.bind(); calling setMulticastTTL/setTTL/setBroadcast/setMulticastInterface on a closed socket; sending or tuning socket options after socket.close().

Common situations: Multicast setup code that assumes bind happened synchronously (it did not — bind is async); reusing a socket object after close in request-scoped code; setup callbacks racing a shutdown flag.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/000b6a59bd7470a8. Report an issue: GitHub.