siyuan-note/siyuan · error · Error

failed to terminate residual kernel processes [ports=" +…

Error message

failed to terminate residual kernel processes [ports=" + residualPorts.join(",") + "]

What it means

During the update flow, after waiting for kernel processes on timed-out ports to exit, some ports still have live kernel processes. On Windows the installer handles killing them, but on non-Windows platforms Electron has no reliable way to kill them, so it aborts the update with this error naming the affected ports.

Solutions

  1. Manually inspect and kill the lingering kernel process for the listed ports (lsof -i :PORT / ps aux | grep siyuan-kernel), then retry the update
  2. Close all other SiYuan workspaces before updating so fewer kernels need to exit
  3. Reboot if the process is unkillable (e.g. stuck in uninterruptible I/O sleep)
  4. On Windows, no action is needed: the installer is expected to terminate residual processes

Example fix

// Hard to fix in caller code; operator-level remediation:
// before
//   update fails: failed to terminate residual kernel processes [ports=6806]
// after
//   $ lsof -i :6806          # find PID holding the port
//   $ kill -9 <pid>
//   # retry the in-app update
Defensive patterns

Strategy: validation

Validate before calling

if !notebookCryptoConfigurationComplete(&Conf.NotebookCrypto) {
    // repair via backup import or re-run EnableEncryptedNotebook before saving
}

Prevention

When it happens

Trigger: An in-app update is initiated while kernel processes from this or other workspaces ignore SIGTERM/SIGKILL within the 5-second waitForKernelProcessExit window on Linux/macOS; residualPorts is non-empty and process.platform !== "win32".

Common situations: A frozen or wedged kernel process holding the workspace port; multiple open workspaces whose kernels have not shut down in time; a kernel stuck in startup/shutdown due to I/O or a deadlock; running the app under a process supervisor that respawns kernels.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/3ad1edd0131fe6dd. Report an issue: GitHub.

Appendix: source

Thrown at app/electron/main.js:1703

    if (timedOutPorts.length === 0) {
        return;
    }

    writeLog("kernel exit timed out before update [ports=" + timedOutPorts.join(",") + "]");
    timedOutPorts.forEach((port) => {
        const kernelProcess = kernelProcesses.get(port);
        if (kernelProcess) {
            writeLog("terminating residual kernel before update [pid=" + kernelProcess.pid + ", port=" + port + "]");
            kernelProcess.kill("SIGKILL");
        }
    });
    await Promise.all(timedOutPorts.map((port) => waitForKernelProcessExit(port, 5000)));
    const residualPorts = timedOutPorts.filter((port) => kernelProcesses.has(port));
    if (residualPorts.length > 0) {
        if (process.platform === "win32") {
            writeLog("residual kernel processes will be terminated by the installer [ports=" + residualPorts.join(",") + "]");
        } else {
            throw new Error("failed to terminate residual kernel processes [ports=" + residualPorts.join(",") + "]");
        }
    }
};

const closeUpdateKernelStage = async (ports, request) => {
    if (ports.length === 0) {
        return [];
    }

    const exitResponses = await Promise.all(ports.map((port) => closeKernelForUpdate(port, request.initiatingPort,
        request.setCurrentWorkspace)));
    ports.forEach((port) => exitApp(port));
    await waitForUpdateKernelExits(ports);
    return exitResponses;
};

// 更新时先退出其他工作空间,再退出发起更新的工作空间,确保安装器启动前所有内核已经停止。
// https://github.com/siyuan-note/siyuan/issues/18258

View on GitHub (pinned to 8641553a1f)