{"record":{"id":"e40e527e05b1b62e","repo":"denoland/deno","slug":"tls-wrap-attach-failed-attachresult","errorCode":null,"errorMessage":"TLS wrap attach failed: ${attachResult}","messagePattern":"TLS wrap attach failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal_binding/tls_wrap.ts","lineNumber":41,"sourceCode":"        : buf.subarray(0, nread);\n      res.receive(data);\n    } else if (nread < 0) {\n      // EOF or error - stop native TCP reads and unref the handle.\n      // Without this, the libuv handle keeps a ref on the event loop\n      // and prevents process exit after the TLS connection ends.\n      nativeHandle.readStop();\n      nativeHandle.unref();\n      res.emitEof();\n    }\n  };\n}\n\nfunction attachNativeHandle(res: TLSWrap, nativeHandle: any) {\n  const attachResult = nativeHandle instanceof PipeWrap\n    ? res.attachPipe(nativeHandle)\n    : res.attach(nativeHandle);\n  if (attachResult !== 0) {\n    throw new Error(`TLS wrap attach failed: ${attachResult}`);\n  }\n\n  installNativeOnread(res, nativeHandle);\n  res._nativeTcpHandle = nativeHandle;\n}\n\n/**\n * Create a TLSWrap that intercepts an underlying stream handle.\n * Mirrors Node's `internalBinding('tls_wrap').wrap(handle, context, isServer)`.\n *\n * @param handle - The underlying stream handle (TCP CppGC object or JSStreamSocket handle)\n * @param context - SecureContext object { ca, cert, key, rejectUnauthorized }\n * @param isServer - Whether this is a server-side TLS connection\n * @param servername - SNI hostname for client connections\n */\nfunction wrap(\n  handle: any,\n  context: any,","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal_binding/tls_wrap.ts#L23-L59","documentation":"In Deno's tls_wrap internal binding, attachNativeHandle wraps an underlying native TCP or Pipe handle into the TLS layer via res.attach()/res.attachPipe(). A non-zero return value is a native error status, thrown as a plain Error including the status code ('TLS wrap attach failed: <code>'). It signals the native side refused to adopt the handle — typically an invalid, closed, or already-used handle.","triggerScenarios":"tls.connect({ socket }) where the net.Socket's native handle is destroyed, already attached to another TLSWrap, or absent (e.g. a socket obtained from an upgrade event or after end()); TLS-over-TLS by re-wapping an already-encrypted TLSSocket; reconnect logic reusing pooled sockets.","commonSituations":"Proxy/tunnel setups that tls.connect over an existing socket; connection-pool reuse where a socket was closed by the peer; wrapping sockets that Deno materialized from a JS transport instead of a real TCP handle (those take the JS-stream path instead).","solutions":["Pass a fresh, connected, unencrypted net.Socket to tls.connect({ socket })","If the socket is already a TLSSocket / already encrypted, use it directly instead of wrapping again","Rebuild the connection: socket.destroy(); sock = net.connect(...); then tls.connect({ socket: sock })"],"exampleFix":"// before\nconst tlsSock = tls.connect({ socket: pooledSocket }); // pooledSocket may be closed/reused\n\n// after\nif (pooledSocket.destroyed || pooledSocket.encrypted) {\n  pooledSocket = net.connect(port, host);\n}\nconst tlsSock = tls.connect({ socket: pooledSocket });","handlingStrategy":"try-catch","validationCode":"const usable = socket &&\n  !socket.destroyed &&\n  !(socket as any).encrypted &&\n  typeof socket._handle === 'object';\nif (!usable) socket = net.connect(port, host);\nconst tlsSock = tls.connect({ socket });","typeGuard":null,"tryCatchPattern":"try {\n  tlsSock = tls.connect({ socket });\n} catch (e: any) {\n  if (/TLS wrap attach failed/.test(e?.message ?? '')) {\n    socket.destroy();\n    const fresh = net.connect(port, host);\n    tlsSock = tls.connect({ socket: fresh });\n  } else throw e;\n}","preventionTips":["tls.connect({ socket }) only over fresh, connected, unencrypted net.Sockets","Check socket.destroyed and pool age before reusing pooled sockets for TLS","Never wrap an already-secure TLSSocket a second time"],"tags":["tls","network","node-compat","sockets"],"backgroundTag":"tls-wrap-attach-failed","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}