Skip to content

service: relaunch fails with "Managed service port already in use" when previous background service has not exited #54267

Open

Description

@abawer

Description

Relaunching opencode can fail with Managed service port 49374 on 127.0.0.1 is already in use by another process when the previous shared background service has not exited.
The client reports the service as missing and spawns a new
opencode serve --service on the same fixed managed port instead of reconnecting
to, or replacing, the still-running one.

Plugins

none found in config (12 built-in plugins reconciled)

OpenCode version

2.0.23

Steps to reproduce

  1. Use opencode so the shared background service starts (default port 49374;
    opencode service get returns {}, no override).
  2. Exit the TUI and immediately launch opencode again while the previous
    opencode serve --service process is still alive / shutting down.
  3. New client logs background service starting reason=missing and spawns
    opencode serve --service, which fails to bind.

Screenshot and/or share link

No response

Operating System

Linux Mint 22.3

Terminal

TERM=xterm-256color, COLORTERM=truecolor

Activity

  1. opencode-agent commented on Oct 10, 2026

    @opencode-agent
    Contributor

    Thanks for the report. I could reproduce this on 2.0.23, and it still happens on the latest v2 (55dde88).

    I couldn't hit the exact quit-and-relaunch timing, so I set up the same state by hand:

    1. Start the shared service with opencode service start (port 49374).
    2. Make the old service still alive but undiscoverable: remove its registration file and pause the process. It keeps the port.
    3. Run opencode service start again.

    The client treats the service as missing and starts a new opencode serve --service. That process retries the bind for about 15 s, and the command fails after about 20 s with Managed service port 49374 on 127.0.0.1 is already in use by another process. The script below reproduces it.

    A plain stop followed immediately by start worked in my tests, so the old process has to keep the port for longer than that bind retry. Once it exits, launching again works. Related: #52234 and #50672 (fixed port with no fallback), #54181 (races during service restart).

    Reproduction script (repro.sh)
    #!/usr/bin/env bash
    # Repro for #54267: a previous managed service that still holds port 49374 but is no
    # longer discoverable (registration gone / not answering, e.g. while shutting down)
    # makes the next launch spawn `opencode serve --service`, which fails to bind.
    #
    # Usage: ./repro.sh            -> uses `opencode` from PATH
    #        OC_DEV=/path/to/repo ./repro.sh -> runs the CLI from a source checkout
    set -u
    H=$(mktemp -d /tmp/opencode/oc54267.XXXX)
    export HOME=$H XDG_DATA_HOME=$H/d XDG_STATE_HOME=$H/s XDG_CONFIG_HOME=$H/c XDG_CACHE_HOME=$H/k
    cd "$H"
    if [ -n "${OC_DEV:-}" ]; then
      # spawned `serve --service` children re-run the entrypoint with plain bun, so use the cli package's bunfig preload
      cd "$OC_DEV/packages/cli"
      OC=(bun --conditions=browser --preload="$OC_DEV/packages/tui/node_modules/@opentui/solid/scripts/preload.js" "$OC_DEV/packages/cli/src/index.ts")
    else
      OC=(opencode)
    fi
    echo "version: $("${OC[@]}" --version)"
    
    echo "== 1. start the shared background service"
    timeout 90 "${OC[@]}" service start
    REG=$(find "$H/s" -name 'service*.json' | head -1)
    cat "$REG"; echo
    PID=$(sed -n 's/.*"pid":\([0-9]*\).*/\1/p' "$REG")
    echo "service pid: $PID"
    
    echo "== 2. simulate a previous service that is still alive (holding the port) but no longer registered"
    rm -f "$REG"
    kill -STOP "$PID"
    
    echo "== 3. relaunch: client sees the service as missing and spawns a new one on the same port"
    time timeout 120 "${OC[@]}" service start 2>&1 | grep -E "already in use|Failed to start|http://" | head -5
    RC=${PIPESTATUS[0]}
    echo "exit code: $RC"
    
    kill -CONT "$PID" 2>/dev/null; kill "$PID" 2>/dev/null
    pkill -f "$H" 2>/dev/null

    Run it: bash repro.sh

  2. AmirHosseinCV commented on Oct 10, 2026

    @AmirHosseinCV

    I'm facing the same issue even when the background service is completely stopped (v2.0.26 - on mac).

    lsof -i :49374

    COMMAND    PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
    opencode  6726 amir    8u  IPv4 0x5f9631d68cbc597f      0t0  TCP localhost:49374 (LISTEN)
    opencode  6726 amir   12u  IPv4 0xebb392ad1e0c65dc      0t0  TCP localhost:49374->localhost:62324 (ESTABLISHED)
    opencode  6726 amir   34u  IPv4 0x63b60b0ddeee25f0      0t0  TCP localhost:49374->localhost:62355 (ESTABLISHED)
    opencode  6726 amir   35u  IPv4 0x7e7133c7bf521527      0t0  TCP localhost:49374->localhost:62356 (ESTABLISHED)
    opencode  6726 amir   36u  IPv4 0x527e323ab1c8c230      0t0  TCP localhost:49374->localhost:62357 (ESTABLISHED)
    opencode 23920 amir   11u  IPv4 0x36d6a491ef4b3f3a      0t0  TCP localhost:62324->localhost:49374 (ESTABLISHED)
    

    kill -9 6726

    opencode2

    Starting background server...
    Error: Server process exited with code 1
    Error: Managed service port 49374 on 127.0.0.1 is already in use by another process. Configure another port with `opencode service set port <port>` and start the service again.
        at <anonymous> (/$bunfs/root/chunk-51degfn7.js:2:8693) {
      [cause]: ServeError: 
          at y (/$bunfs/root/chunk-a2av342k.js:52:46739)
          at applyHandlers (node:events:64:20)
          at emitError (node:events:44:27)
          at emitListenErrorNextTick (node:_http_server:134:12)
          at processTicksAndRejections (unknown:7:39) {
        [cause]: Error: Failed to start server. Is port 49374 in use?
            at serve (unknown)
            at <anonymous> (node:_http_server:359:39)
            at <anonymous> (node:_http_server:332:33)
            at <anonymous> (/$bunfs/root/chunk-a2av342k.js:52:46777)
      }
    }
        at map (unknown:1:11)
        at reap (/$bunfs/root/chunk-n8d8mk37.js:2:1159)
        at <anonymous> (/$bunfs/root/chunk-n8d8mk37.js:3:6711)
        at service.ensure (/$bunfs/root/chunk-ktw99a5w.js:3:690)
        at service.ensure (definition) (/$bunfs/root/chunk-n8d8mk37.js:3:5523)
        at cli.server-connection.resolve (/$bunfs/root/chunk-pdhrztb8.js:96:6563)
        at cli.server-connection.resolve (definition) (/$bunfs/root/chunk-ktw99a5w.js:2:402)
    

    Stopping and starting the service manually fails too:

    opencode2 service stop

    lsof -i :49374 (shows no output)

    opencode2 service start

    Error: Server process exited with code 1
    Error: Managed service port 49374 on 127.0.0.1 is already in use by another process. Configure another port with `opencode service set port <port>` and start the service again.
        at <anonymous> (/$bunfs/root/chunk-51degfn7.js:2:8693) {
      [cause]: ServeError: 
          at y (/$bunfs/root/chunk-a2av342k.js:52:46739)
          at applyHandlers (node:events:64:20)
          at emitError (node:events:44:27)
          at emitListenErrorNextTick (node:_http_server:134:12)
          at processTicksAndRejections (unknown:7:39) {
        [cause]: Error: Failed to start server. Is port 49374 in use?
            at serve (unknown)
            at <anonymous> (node:_http_server:359:39)
            at <anonymous> (node:_http_server:332:33)
            at <anonymous> (/$bunfs/root/chunk-a2av342k.js:52:46777)
      }
    }
        at map (unknown:1:11)
        at reap (/$bunfs/root/chunk-n8d8mk37.js:2:1159)
        at <anonymous> (/$bunfs/root/chunk-n8d8mk37.js:3:6711)
        at service.ensure (/$bunfs/root/chunk-mjpv4441.js:2:862)
        at service.ensure (definition) (/$bunfs/root/chunk-n8d8mk37.js:3:5523)
        at cli.service.start (/$bunfs/root/chunk-4r3q3xdc.js:7:19760)
        at cli.service.start (definition) (/$bunfs/root/chunk-mjpv4441.js:2:807)
    

    Even chaning the port using opencode2 service set port 49375 didn't help.

  3. abawer commented on Oct 10, 2026

    @abawer
    Author

    sudo pkill -f opencode
    does the cleanup for me between reruns on Linux.

  4. AmirHosseinCV commented on Oct 10, 2026

    @AmirHosseinCV

    5. sudo pkill -f opencode
    does the cleanup for me between reruns on Linux.

    Thanks for the suggestion, but it didn't work on my Mac.

  5. psno commented on Oct 12, 2026

    @psno

    Reproduced on 2.0.27, and I think the logs add the missing link in the chain: the client decides the service is missing while the service is still booting and answering /api/info with 503, then spawns a competing serve --service on the fixed managed port.

    Environment

    • opencode 2.0.27 (channel latest); Linux 5.15.167.4-microsoft-standard-WSL2 x86_64
    • Existing DB ~/.local/share/opencode/opencode.db: 620 MB, V1→V2 migrated, WAL
    • No port override (~/.local/state/opencode/service.json uses 49374)

    Evidence

    Two clients started ~140 ms apart at 2026-10-12T05:27:59Z:

    run=66873b87 message="cli starting" version=2.0.27 args=[] role=cli
    run=66873b87 message="background service starting" reason=missing previousVersion=undefined role=cli
    run=65676499 message="cli starting" version=2.0.27 args="[\"serve\",\"--service\"]" role=cli
    run=65676499 message="Sent HTTP response" http.method=GET http.url=/api/info http.status=503
    run=65676499 message="location services booted" directory=/mnt/e/... durationMs=22302 http.span=24425 role=server
    

    So /api/info answered 503 for the whole ~22 s cold boot, during which the other client logged reason=missing and tried to launch its own managed service. The user-visible failure is exactly the one reported here:

    Error: Managed service port 49374 on 127.0.0.1 is already in use by another process.
    

    After boot the daemon is healthy — /api/info returns 200 {"version":"2.0.27","pid":10332,...}, and the API works with Basic auth (opencode + the password in ~/.local/state/opencode/service.json) — but the disagreement is permanent for the rest of the session:

    • opencode service status still prints stopped
    • every CLI subcommand that needs the service (opencode session list, opencode plugin list, …) fails with the port error instead of reconnecting to the healthy daemon

    Suggestion

    Treat a 503 from /api/info during startup as "starting" rather than "missing" (or retry/bound the ensure() wait), so a client never spawns a second managed service while the first is still booting, and make service status agree with a daemon that is actually reachable.

    The long bootstrap here may be the same family as #41739 (slow startup with a large migrated SQLite database); this DB is 620 MB rather than 28 GB, but it is still an order of magnitude above a fresh install.

  6. psno commented on Oct 12, 2026

    @psno

    Second, unrelated root cause for the same message (Windows): reserved port ranges

    Adding a data point, because this exact error text has a different cause on Windows.

    • opencode 2.0.27, Windows 11 (native, not WSL), DB ~300 MB
    • The message is the one from the OP:
    Error: Managed service port 49374 on 127.0.0.1 is already in use by another process.
    

    Nothing is actually holding the port:

    netstat -ano | findstr 49374   -> no match
    connect 127.0.0.1:49374        -> actively refused
    bind    127.0.0.1:49374        -> "An attempt was made to access a socket in a way forbidden by its access permissions"
    

    The real cause is a Windows TCP port exclusion (Hyper-V / WinNAT reservations), which happens to cover opencode's default managed port:

    > netsh interface ipv4 show excludedportrange protocol=tcp
    Start Port    End Port
    ...
    49208        49307
    49360        49459      <-- 49374 is inside this range
    50000        50059  *
    

    bind() on a reserved port fails with WSAEACCES, and the CLI surfaces that as "already in use ... Is port 49374 in use?", which sends you hunting for a process that does not exist.

    These dynamic reservations are re-allocated at boot, so a port that worked for months can start failing after a reboot with no config change on the opencode side.

    Workaround: move the managed port outside the Windows dynamic range (default 49152-65535):

    opencode service set port 19474
    opencode service start
    

    That immediately restored service status, session list, plugin list, etc.

    Suggestion: on Windows, distinguish EACCES/WSAEACCES from EADDRINUSE and report it as "port is reserved by the system (see netsh interface ipv4 show excludedportrange protocol=tcp)" rather than "already in use" — and/or default the managed port below 49152.

  7. abawer commented on Oct 12, 2026

    @abawer
    Author

    As for Linux Mint 22.3 the 49374 port is still on LISTEN state afer /exit from opencode console

    tcp        0      0 127.0.0.1:49374         0.0.0.0:*               LISTEN      235811/opencode   
    

    Using opencode v2.0.23

  8. added 3 commits that reference this issue on Oct 14, 2026
    c5bdc02
    80e68c6
    7b38c2e
  9. Cofeesy commented on Oct 16, 2026

    @Cofeesy

    v2.0.30 has the same problem, killing the port or setting the port to 49395 still not work

  10. Hk-Gosuto commented on Oct 17, 2026

    @Hk-Gosuto

    I ran into this issue too. It seems to be related to permissions—after I ran sudo opencode, everything worked fine.

  11. Cofeesy commented on Oct 17, 2026

    @Cofeesy

    16. v2.0.30 has the same problem, killing the port or setting the port to 49395 still not work

    sudo opencode solved the problem.

  12. neriousy commented on Oct 19, 2026

    @neriousy
    Member

    Several of you hit this with different setups, and it looks like more than one cause produces the same message. Two of you said sudo opencode fixed it, which points to a service or data files owned by root from an earlier sudo run. If you're still affected, could you share:

    1. OS and opencode --version, and how you installed it.
    2. While it's failing, who owns the port: lsof -nP -iTCP:<port> (macOS/Linux) or netstat -ano | findstr :<port> plus tasklist /FI "PID eq <pid>" (Windows). Please include the user column.
    3. Have you ever run opencode with sudo or as Administrator? The output of ls -la ~/.local/share/opencode ~/.local/state/opencode helps here.
    4. Are any of XDG_STATE_HOME, XDG_DATA_HOME, HTTP_PROXY, HTTPS_PROXY, ALL_PROXY or NO_PROXY set? Are you on WSL, and if so which networking mode?
    5. Do other opencode installs or opencode-based apps run on the same machine (Desktop, another CLI install, Kilo)?
    6. When it happens: right after quitting a session, after an update, or after a reboot?
  13. AmirHosseinCV commented on Oct 19, 2026

    @AmirHosseinCV

    For me, the issue was caused by the http_proxy environment variable. Unsetting it or adding localhost and 127.0.0.1 to NO_PROXY fixed it.

  14. mikehaller commented on Oct 20, 2026

    @mikehaller

    29. For me, the issue was caused by the http_proxy environment variable. Unsetting it or adding localhost and 127.0.0.1 to NO_PROXY fixed it.

    Similar for me, i had "127.0.0.1/8" in NO_PROXY and opencode didn't start. I added an additional 127.0.0.1/ entry and then opencode started again. So, it seems the CIDR ranges are not really supported by OpenCode/NodeJS

    CIDR ranges in NO_PROXY are not supported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions