{"record":{"id":"346d8c9ccb2a3ea9","repo":"sveltejs/kit","slug":"only-one-socket-is-allowed-for-socket-activation","errorCode":null,"errorMessage":"only one socket is allowed for socket activation, but LISTEN_FDS was set to ${listen_fds}","messagePattern":"only one socket is allowed for socket activation, but LISTEN_FDS was set to (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/adapter-node/src/index.js","lineNumber":24,"sourceCode":"import { rm } from 'node:fs/promises';\nimport { format_listening_address } from './utils.js';\n\nexport const path = env('SOCKET_PATH', false);\nexport const host = env('HOST', '0.0.0.0');\nexport const port = env('PORT', !path && '3000');\n\nconst shutdown_timeout = parseInt(env('SHUTDOWN_TIMEOUT', '30'));\nconst idle_timeout = parseInt(env('IDLE_TIMEOUT', '0'));\nconst listen_pid = parseInt(env('LISTEN_PID', '0'));\nconst listen_fds = parseInt(env('LISTEN_FDS', '0'));\n// https://www.freedesktop.org/software/systemd/man/latest/sd_listen_fds.html\nconst SD_LISTEN_FDS_START = 3;\n\nif (listen_pid !== 0 && listen_pid !== process.pid) {\n\tthrow new Error(`received LISTEN_PID ${listen_pid} but current process id is ${process.pid}`);\n}\nif (listen_fds > 1) {\n\tthrow new Error(\n\t\t`only one socket is allowed for socket activation, but LISTEN_FDS was set to ${listen_fds}`\n\t);\n}\n\nconst socket_activation = listen_pid === process.pid && listen_fds === 1;\n\nlet requests = 0;\n/** @type {NodeJS.Timeout | void} */\nlet shutdown_timeout_id;\n/** @type {NodeJS.Timeout | void} */\nlet idle_timeout_id;\n\nconst httpServer = http.createServer();\n\nconst keep_alive_timeout = timeout_env('KEEP_ALIVE_TIMEOUT');\nif (keep_alive_timeout !== undefined) {\n\t// Convert the keep-alive timeout from seconds to milliseconds (the unit Node.js expects).\n\thttpServer.keepAliveTimeout = keep_alive_timeout * 1000;","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/adapter-node/src/index.js#L6-L42","documentation":"The sd_listen_fds socket-activation protocol can pass multiple inherited file descriptors, but adapter-node is designed to take over exactly one listening socket. If LISTEN_FDS reports more than one, the adapter cannot know which to use and throws instead of guessing.","triggerScenarios":"LISTEN_FDS is set to a value greater than 1 in the environment when the adapter-node server starts.","commonSituations":"systemd socket unit defines multiple ListenStream/Liste­nDatagram entries; several sockets are passed to the service; a leftover LISTEN_FDS env var leaks into a non-socket-activated deployment.","solutions":["Reduce the systemd socket unit to a single ListenStream= (split extra ports into separate services)","Unset LISTEN_FDS if you do not intend to use socket activation: `env -u LISTEN_FDS node build`","Handle additional ports inside the SvelteKit app or a reverse proxy instead of via multiple activated sockets","Check `systemctl show <socket> -p Listen` to count how many fds the unit passes"],"exampleFix":"# before (myapp.socket)\n[Socket]\nListenStream=3000\nListenStream=3001\n# after\n[Socket]\nListenStream=3000","handlingStrategy":"validation","validationCode":"const fds = parseInt(process.env.LISTEN_FDS ?? '0', 10);\nif (fds > 1) throw new Error(`socket activation expects 1 fd, got ${fds}; fix your .socket unit`);","typeGuard":"const hasSingleActivatedSocket = (env = process.env) => {\n  const n = parseInt(env.LISTEN_FDS ?? '0', 10);\n  return Number.isFinite(n) && n <= 1;\n};","tryCatchPattern":"try {\n  startServer();\n} catch (err) {\n  if (/LISTEN_FDS/.test(err.message)) {\n    console.error('Multiple activated sockets not supported — use a single ListenStream.');\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Keep one ListenStream= per systemd .socket unit","`systemctl show <socket> -p Listen` to verify fd count before deploy","Unset LISTEN_FDS in non-socket-activated environments","Route extra ports through a reverse proxy instead of extra sockets"],"tags":["node","socket-activation","environment","systemd"],"backgroundTag":"socket-activation-multiple-fds","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}