Node.js简易服务器无论端口如何均抛出EBADF错误
Node.js 16/18 HTTP服务器首次请求抛出Error: accept EBADF(Ubuntu 22)
问题重现
运行以下最简HTTP服务器代码:
const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello, World!\n'); }); const PORT = 3000; server.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}/`); });
- 进程可成功绑定端口,但首次发起请求时直接崩溃,抛出错误:
node:events:495 throw er; // Unhandled 'error' event ^ Error: accept EBADF at TCP.onconnection (node:net:2050:24) Emitted 'error' event on Server instance at: at TCP.onconnection (node:net:2050:10) { errno: -9, code: 'EBADF', syscall: 'accept' }
- 更换端口无效果,仅在Node.js 16/18版本出现,Node.js 20版本正常,运行环境为Ubuntu 22。
问题原因
这是Node.js 16/18版本与Ubuntu 22内核的兼容性bug,EBADF代表无效文件描述符,Node.js在处理TCP连接的accept调用时出现了底层资源管理问题,该问题已在Node.js 20版本中被官方修复。
解决方案
升级到Node.js 20+ LTS版本
这是最彻底的解决方案,直接使用无此bug的版本,完全规避兼容性问题。更新至Node.js 16/18的最新补丁版本
若因依赖限制无法升级到20+,可以尝试安装对应大版本的最新小版本(比如Node.js 16.20.x或18.17.x),后续补丁可能已针对Ubuntu 22的内核环境修复了该问题。临时捕获错误避免进程崩溃(仅应急)
若暂时无法升级版本,可手动监听Server的error事件捕获错误,防止进程直接崩溃,但无法解决根本问题:const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello, World!\n'); }); // 添加错误监听 server.on('error', (err) => { console.error('服务器错误:', err); }); const PORT = 3000; server.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}/`); });
内容的提问来源于stack exchange,提问作者pseudosudo
相关产品推荐
相关产品推荐

