{"record":{"id":"9669c01d7ef3fee6","repo":"denoland/deno","slug":"err-socket-already-bound","errorCode":"ERR_SOCKET_ALREADY_BOUND","errorMessage":"Socket is already bound","messagePattern":"Socket is already bound","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/dgram.ts","lineNumber":413,"sourceCode":"   * server.bind(41234);\n   * // Prints: server listening 0.0.0.0:41234\n   * ```\n   *\n   * @param callback with no parameters. Called when binding is complete.\n   */\n  bind(port?: number, address?: string, callback?: () => void): this;\n  bind(port: number, callback?: () => void): this;\n  bind(callback: () => void): this;\n  bind(options: BindOptions, callback?: () => void): this;\n  bind(port_?: unknown, address_?: unknown /* callback */): this {\n    let port = typeof port_ === \"function\" ? null : port_;\n\n    healthCheck(this);\n\n    const state = this[kStateSymbol];\n\n    if (state.bindState !== BIND_STATE_UNBOUND) {\n      throw new ERR_SOCKET_ALREADY_BOUND();\n    }\n\n    state.bindState = BIND_STATE_BINDING;\n\n    const cb = arguments.length && arguments[arguments.length - 1];\n\n    if (typeof cb === \"function\") {\n      // deno-lint-ignore no-inner-declarations\n      function removeListeners(this: Socket) {\n        this.removeListener(\"error\", removeListeners);\n        this.removeListener(\"listening\", onListening);\n      }\n\n      // deno-lint-ignore no-inner-declarations\n      function onListening(this: Socket) {\n        FunctionPrototypeCall(removeListeners, this);\n        FunctionPrototypeCall(cb, this);\n      }","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/node/polyfills/dgram.ts#L395-L431","documentation":"Socket.bind() refuses to run unless the socket is in the BIND_STATE_UNBOUND state: binding again while a bind is in progress or after it completed throws ERR_SOCKET_ALREADY_BOUND. A dgram socket owns exactly one bind per lifetime; rebinding requires a new socket.","triggerScenarios":"s.bind(41234) called twice on the same socket; bind() racing with connect(), which auto-binds ({ port: 0, exclusive: true }) when the socket is unbound; retry logic that rebinds on error instead of closing and recreating the socket.","commonSituations":"Reconnect/retry loops that reuse the socket; startup code that binds in two places (e.g. init and an explicit start function); mixing manual bind with connect's implicit bind.","solutions":["Bind once per Socket instance; create a new socket (createSocket('udp4')) to bind again","Sequence startup with the 'listening' and 'error' events instead of re-calling bind","In connect()-based flows, drop the manual bind and let connect auto-bind"],"exampleFix":"// before\nsock.bind(port);\nsock.bind(port); // retry on slow start — throws\n// after\nsock.bind(port);\nsock.once(\"listening\", () => console.log(\"bound\"));\nsock.once(\"error\", (e) => { sock.close(); sock = dgram.createSocket(\"udp4\"); sock.bind(port); });","handlingStrategy":"validation","validationCode":"let bound = false;\nfunction bindOnce(sock, ...args) {\n  if (bound) return sock;\n  bound = true;\n  return sock.bind(...args);\n}\nsock.once(\"listening\", () => { bound = true; });\nsock.once(\"close\", () => { bound = false; });","typeGuard":null,"tryCatchPattern":"try { sock.bind(port); }\ncatch (e) {\n  if (e.code === \"ERR_SOCKET_ALREADY_BOUND\") { /* already listening; continue */ }\n  else throw e;\n}","preventionTips":["One bind per socket; recreate the socket to rebind","Sequence startup with 'listening'/'error' events, not repeated bind calls","Remember connect() implicitly binds an unbound socket"],"tags":["dgram","udp","bind","state-machine"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}