app-server WS handshake fails with iOS URLSessionWebSocketTask (-1005) before initialize

Open 💬 5 comments Opened Feb 19, 2026 by shuto-S

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

  1. Start server:

``bash
codex app-server --listen ws://0.0.0.0:8080
``

  1. Connect from iOS app via URLSessionWebSocketTask to either:
  • ws://{host}:{port}
  1. 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:

  1. Tolerate/ignore unsupported extension negotiation from clients like iOS URLSession, or
  2. Offer a flag/config to disable extension negotiation requirements for compatibility?

Happy to test a branch/build if needed.

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗