You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: opencode serve does not release port on exit — zombie self-loopback connection locks LISTENING socket (Windows) #32932
When opencode serve exits or crashes, the server port (e.g. 4096) is not released. A self-loopback TCP connection (127.0.0.1:54420 ↔ 127.0.0.1:4096, both endpoints owned by the now-dead server PID) remains in ESTABLISHED state, keeping the LISTENING socket locked. On Windows, this port cannot be reclaimed by a new opencode serve --port 4096 invocation — it fails with ServeError: Unexpected error.
The dead process (PID 19152) no longer exists in the process table, but the Windows kernel TCP stack keeps the socket open because the self-loopback ESTABLISHED connection never receives a FIN/RST from either end. All other client connections are stuck in CLOSE_WAIT, also waiting on this zombie self-connection.
This is related to #22198 (SSE connections stuck in CLOSE_WAIT) but is a distinct issue: the root cause here is that opencode serve does not perform graceful socket shutdown on exit, leaving a self-loopback connection that locks the listening port indefinitely on Windows.
Dead PID still holds LISTENING: netstat -ano shows LISTENING 127.0.0.1:4096 PID 19152, but tasklist /fi "pid eq 19152" → "No tasks running which match the specified criteria"
Self-loopback ESTABLISHED: netstat -ano shows 127.0.0.1:54420 ↔ 127.0.0.1:4096 ESTABLISHED PID 19152 on both sides — a connection from the server to itself that was never closed
54+ CLOSE_WAIT connections: All other connections to port 4096 are in CLOSE_WAIT, waiting on the zombie self-connection
Port never releases: Killed all OpenCode Desktop processes, killed all Edge browser processes, waited several minutes — port 4096 still held by dead PID 19152. Only a full OS reboot clears it.
Steps to reproduce
Start opencode serve --port 4096 (WSL2 or Windows)
Open OpenCode Desktop and connect it to the server (this creates SSE connections including self-loopback)
Kill the opencode serve process (e.g. close the terminal, or the process crashes)
Verify with netstat -ano | findstr 4096: LISTENING socket still held by dead PID, with a self-loopback ESTABLISHED connection
Expected behavior
opencode serve should perform graceful shutdown on exit:
Close all SSE streams and send FIN to connected clients
Close the self-loopback connection (if any)
Close the LISTENING socket
The port should be immediately available for a new instance
Suggested fix
Register a process exit handler (process.on('exit'), process.on('SIGTERM'), process.on('SIGINT')) that calls server.close() and closes all active connections
On Windows, also call server.removeAllListeners() and explicitly destroy sockets that are in CLOSE_WAIT
Consider adding a TCP keepalive/idle timeout on SSE connections so zombie connections eventually self-close even if the server process dies ungracefully
I also use local drop-ins for authentication and proxy settings. For example, the authentication drop-in should look like this, with your own password:
Using systemd as the supervisor has worked around the issue for me: when the process exits or fails, systemd owns the process lifecycle and restarts the service, so I have not encountered the stuck-port problem for a long time.
This is only a workaround, not a fix in OpenCode itself. Running opencode web or opencode serve directly, outside systemd, may still reproduce the same issue.
Activity
HaonanQiu commentedon Jul 8, 2026
same problem
arashi-dev commentedon Jul 22, 2026
Any updates? I still have this problem and looks like there is something going on here aictrl-dev/cli#94
WhiteGiverMa commentedon Jul 22, 2026
now I use systemd to manage opencode service in WSL so I didnt meet this for a long time.
arashi-dev commentedon Jul 23, 2026
@WhiteGiverMa That's sounds interesting, can you share your systemd config please?
WhiteGiverMa commentedon Jul 23, 2026
@arashi-dev Sure. This is the user-level systemd unit I use in WSL (
~/.config/systemd/user/opencode-serve.service):I enable and start it with:
systemctl --user daemon-reload systemctl --user enable --now opencode-serve.serviceI also use local drop-ins for authentication and proxy settings. For example, the authentication drop-in should look like this, with your own password:
Using systemd as the supervisor has worked around the issue for me: when the process exits or fails, systemd owns the process lifecycle and restarts the service, so I have not encountered the stuck-port problem for a long time.
This is only a workaround, not a fix in OpenCode itself. Running
opencode weboropencode servedirectly, outside systemd, may still reproduce the same issue.arashi-dev commentedon Jul 23, 2026
@WhiteGiverMa Thank you very much!
github-actions commentedon Sep 22, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.