{"record":{"id":"9a0636d6718bf6ff","repo":"denoland/deno","slug":"err-http2-socket-unbound","errorCode":"ERR_HTTP2_SOCKET_UNBOUND","errorMessage":"The socket has been disconnected from the Http2Session","messagePattern":"The socket has been disconnected from the Http2Session","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/http2.ts","lineNumber":811,"sourceCode":"      case \"setTimeout\":\n      case \"ref\":\n      case \"unref\":\n        return FunctionPrototypeBind(session[prop], session);\n      case \"destroy\":\n      case \"emit\":\n      case \"end\":\n      case \"pause\":\n      case \"read\":\n      case \"resume\":\n      case \"write\":\n      case \"setEncoding\":\n      case \"setKeepAlive\":\n      case \"setNoDelay\":\n        throw new ERR_HTTP2_NO_SOCKET_MANIPULATION();\n      default: {\n        const socket = session[kSocket];\n        if (socket === undefined) {\n          throw new ERR_HTTP2_SOCKET_UNBOUND();\n        }\n        const value = socket[prop];\n        return typeof value === \"function\"\n          ? FunctionPrototypeBind(value, socket)\n          : value;\n      }\n    }\n  },\n  getPrototypeOf(session) {\n    const socket = session[kSocket];\n    if (socket === undefined) {\n      throw new ERR_HTTP2_SOCKET_UNBOUND();\n    }\n    return ReflectGetPrototypeOf(socket);\n  },\n  set(session, prop, value) {\n    switch (prop) {\n      case \"setTimeout\":","sourceCodeStart":793,"sourceCodeEnd":829,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/http2.ts#L793-L829","documentation":"The Http2Session socket proxy's get trap allows a passthrough for properties not on the banned list, but only if session[kSocket] is still bound. Once the session is destroyed/closed the socket is detached, and reading any non-banned property (remoteAddress, writable, etc.) throws ERR_HTTP2_SOCKET_UNBOUND: 'The socket has been disconnected from the Http2Session'.","triggerScenarios":"Reading session.socket.remoteAddress / remotePort / encrypted in a 'close' or shutdown handler; logging socket details inside an error handler that runs after session.destroy(); accessing session.socket properties after a GOAWAY or fatal error unbound the socket.","commonSituations":"Access-log or audit middleware that inspects the peer address at request end, which can race session teardown; graceful-shutdown code that iterates sessions and inspects sockets after closing them; error reporters digging into socket state post-mortem.","solutions":["Guard with if (!session.destroyed && !session.closed) before reading session.socket properties","Capture the peer details (remoteAddress, remotePort) once, early in the session lifetime, and reuse the snapshot","Register 'close' listeners that stop referencing session.socket rather than reading it"],"exampleFix":"// before\nsession.on('close', () => {\n  log(session.socket.remoteAddress); // throws ERR_HTTP2_SOCKET_UNBOUND\n});\n\n// after\nconst peer = session.socket.remoteAddress; // captured while bound\nsession.on('close', () => log(peer));","handlingStrategy":"validation","validationCode":"const socketInfo = (session: Http2Session) =>\n  session.destroyed || session.closed\n    ? undefined\n    : { addr: session.socket.remoteAddress, port: session.socket.remotePort };","typeGuard":"const hasBoundSocket = (session: Http2Session): boolean =>\n  !session.destroyed && !session.closed;","tryCatchPattern":"try {\n  log(session.socket.remoteAddress);\n} catch (err) {\n  if ((err as NodeJS.ErrnoException).code === 'ERR_HTTP2_SOCKET_UNBOUND') {\n    // session already tore down; use a snapshot captured earlier\n  } else throw err;\n}","preventionTips":["Snapshot remoteAddress/remotePort when the session opens and reuse the snapshot","Check session.destroyed/session.closed before any session.socket access","Do not inspect sockets inside 'close' or shutdown handlers"],"tags":["http2","socket","session-lifecycle","node-compat"],"backgroundTag":"socket-disconnected","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}