Summary
sprite exec automatically detects when a process inside the sprite listens
on a TCP port and binds the same port locally for forwarding. This behavior
is undocumented and silently conflicts with sprite proxy on the same port.
What happens
# 1. Port 7777 is free locally
lsof -ti :7777 # (no output)
# 2. Start a TCP listener inside the sprite via sprite exec
sprite exec -s my-sprite -- python3 -c "
import socket, time
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 7777))
s.listen(1)
print('Listening on 7777', flush=True)
time.sleep(30)
" &
sleep 5
# 3. Local port 7777 is now bound by the sprite CLI process
lsof -i :7777
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# sprite ... user 7u IPv4 ... 0t0 TCP *:7777 (LISTEN)
# 4. sprite proxy fails — port already taken
sprite proxy -s my-sprite 7777
# Error: failed to listen on port 7777: listen tcp 127.0.0.1:7777:
# bind: address already in use
Tested on two independent ports (7777, 9876) on a dedicated sprite. The
auto-forwarding appears to work for TCP connections — the issue is not that
it's broken, but that it's invisible and conflicts with the documented
forwarding mechanism.
The interaction
The auto-forwarding is non-aggressive: if sprite proxy is started first,
sprite exec detects the port is occupied and skips the auto-bind. Both
work correctly in that order. But the natural order (start the process first,
then forward its port) fails silently.
What would help
-
Document the auto-forwarding behavior in the sprite exec docs. The
current docs describe exec as "run a single command, wait for it to finish,
get the output" — no mention of port binding. Users who also use
sprite proxy need to know about the interaction.
-
Add a --no-port-forward flag (or similar) on sprite exec so users
can disable the auto-forwarding when they use sprite proxy explicitly.
-
Improve the sprite proxy error message. When the port is held by
another sprite process, the error could mention this — instead of the
generic "address already in use" which sends users looking for unrelated
processes.
Environment
- Sprite CLI: current as of 2026-03-09
- OS: Linux (Ubuntu)
- Tested on a clean sprite with no services running
Summary
sprite execautomatically detects when a process inside the sprite listenson a TCP port and binds the same port locally for forwarding. This behavior
is undocumented and silently conflicts with
sprite proxyon the same port.What happens
Tested on two independent ports (7777, 9876) on a dedicated sprite. The
auto-forwarding appears to work for TCP connections — the issue is not that
it's broken, but that it's invisible and conflicts with the documented
forwarding mechanism.
The interaction
The auto-forwarding is non-aggressive: if
sprite proxyis started first,sprite execdetects the port is occupied and skips the auto-bind. Bothwork correctly in that order. But the natural order (start the process first,
then forward its port) fails silently.
What would help
Document the auto-forwarding behavior in the
sprite execdocs. Thecurrent docs describe exec as "run a single command, wait for it to finish,
get the output" — no mention of port binding. Users who also use
sprite proxyneed to know about the interaction.Add a
--no-port-forwardflag (or similar) onsprite execso userscan disable the auto-forwarding when they use
sprite proxyexplicitly.Improve the
sprite proxyerror message. When the port is held byanother
spriteprocess, the error could mention this — instead of thegeneric "address already in use" which sends users looking for unrelated
processes.
Environment