# SC302：退出后端口仍未关闭

> SC302（退出后端口仍未关闭）表示启动的进程已经退出，但 HTTP 端口仍在接受连接，说明有子服务器还在运行。本文说明如何修复。

Source: https://shutdown.jscrate.dev/zh/docs/codes/sc302
Last updated: 2026-09-23

`SC302` 表示 shutdown-check 启动的进程退出了，但 HTTP 端口仍被另一个进程占用。常见原因是 shell 或包管理器这类包装进程把真正的服务器作为子进程启动，却没有转发 `SIGTERM`。

| | |
| --- | --- |
| 诊断码 | `SC302` (FAIL) |
| 阶段 | 进程退出 |
| CLI 退出码 | 1 |
| 含义 | 启动的进程已经退出，但 HTTP 端口仍在接受连接：有子服务器还在运行。 |
| 输出信息 | `The launch process exited, but the HTTP port is still open or did not clearly refuse a connection (possible child process left running)` |
| 首先检查 | 直接启动服务器；或者确保启动它的包装进程或进程管理器会把 SIGTERM 转发给真正的服务器，并等待它退出。 |

## 如何修复？

直接启动服务器进程：

```json title="shutdown-check.json"
{
  "command": ["node", "dist/server.js"]
}
```

避免使用会多出一层进程的命令，例如 `npm start`、`sh -c`，或者把服务器放到后台运行的脚本。如果必须使用包装进程，让它用服务器进程替换自身，或者转发信号并等待子进程退出。

测试在报告失败后会清理整个进程组，所以 shutdown-check 结束后，子进程不应该还留着。

## 如何确认已修复？

用新的直接命令再运行一次。通过的运行最后会依次出现：进程退出、端口拒绝连接，以及 `shutdown verified`。

如果必须使用包装进程，就把它作为启动命令来测试。不要测试时直接启动 `node`，部署时却走另一条信号路径；那样会漏掉原本的 bug。

## 相关内容

- [配置直接的启动命令](https://shutdown.jscrate.dev/zh/docs/configuration#command-cwd-and-env)
- [容器与 PID 1](https://shutdown.jscrate.dev/zh/docs/guides/kubernetes#why-does-pid-1-matter)
- [SC300：服务未退出](https://shutdown.jscrate.dev/zh/docs/codes/sc300)
- [SC301：退出码错误](https://shutdown.jscrate.dev/zh/docs/codes/sc301)
