app-server WS handshake fails with iOS URLSessionWebSocketTask (-1005) before initialize
Summary
When connecting to codex app-server from an iOS client (URLSessionWebSocketTask), TCP connection reaches the server, but the WebSocket session drops immediately on iOS with NSURLErrorDomain Code=-1005 before JSON-RPC initialize can start.
Environment
- Codex CLI:
codex-cli 0.104.0 - Server start command:
``bash``
codex app-server --listen ws://0.0.0.0:8080
- Listener check:
``bash``
lsof -nP -iTCP:8080 -sTCP:LISTEN
# codex-aar ... TCP *:8080 (LISTEN)
- Client: iOS app (Swift +
URLSessionWebSocketTask) - Network: same Tailscale tailnet (closed/private network)
Reproduction
- Start server:
``bash``
codex app-server --listen ws://0.0.0.0:8080
- Connect from iOS app via
URLSessionWebSocketTaskto either:
ws://{host}:{port}
- Attempt to connect and begin app-server session.
Expected
WebSocket handshake succeeds and app-server can proceed to JSON-RPC initialize.
Actual
iOS immediately reports connection lost (-1005) and app-server session cannot initialize.
iOS logs
Task <09A1000B-A247-490A-8542-EFBC39F47539>.<4> HTTP load failed, 696/0 bytes (error code: -1005 [4:-4])
Task <09A1000B-A247-490A-8542-EFBC39F47539>.<4> finished with error [-1005] Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSErrorFailingURLStringKey=http://100.103.155.65:8080/, NSErrorFailingURLKey=http://100.103.155.65:8080/, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalWebSocketTask <09A1000B-A247-490A-8542-EFBC39F47539>.<4>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalWebSocketTask <09A1000B-A247-490A-8542-EFBC39F47539>.<4>, NSLocalizedDescription=The network connection was lost.}
Task <CFFE1E8F-BF3E-4E35-B2C5-57508D91EFA0>.<5> HTTP load failed, 696/0 bytes (error code: -1005 [4:-4])
Task <CFFE1E8F-BF3E-4E35-B2C5-57508D91EFA0>.<5> finished with error [-1005] Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSErrorFailingURLStringKey=http://100.103.155.65:8080/, NSErrorFailingURLKey=http://100.103.155.65:8080/, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalWebSocketTask <CFFE1E8F-BF3E-4E35-B2C5-57508D91EFA0>.<5>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalWebSocketTask <CFFE1E8F-BF3E-4E35-B2C5-57508D91EFA0>.<5>, NSLocalizedDescription=The network connection was lost.}
app-server logs
codex app-server (WebSockets)
listening on: ws://0.0.0.0:8080
note: this is a raw WS server; consider running behind TLS/auth for real remote use
websocket client connected from 100.103.155.65:64251
websocket client connected from 100.103.155.65:64254
(Repeated attempts show many websocket client connected ... lines, but iOS side still fails before usable session.)
Notes / suspicion
I suspect a handshake compatibility problem around Sec-WebSocket-Extensions (e.g. permessage-deflate) from iOS URLSessionWebSocketTask, which cannot easily disable extension negotiation.
Could app-server either:
- Tolerate/ignore unsupported extension negotiation from clients like iOS URLSession, or
- Offer a flag/config to disable extension negotiation requirements for compatibility?
Happy to test a branch/build if needed.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗