Skip to content

Proxy crashes on refused HTTPS upstream connection and kills the wrapped command's process tree #1

Description

@zpnichols

Environment: Socket Firewall Free 1.13.1 (npm sfw 2.0.6), macOS arm64 (Darwin 25.5)

Summary

When a client behind sfw's injected proxy makes an HTTPS request to an upstream that refuses the connection, sfw does not return a gateway error to the client — the proxy process crashes with an unhandled ECONNREFUSED, and the wrapped command's entire process tree is killed mid-run. (It then exits 0; filed separately as its own issue since either fix stands alone.)

Reproduction (deterministic, fully local)

Nothing listens on 127.0.0.1:9, so the proxy's upstream connect is refused:

$ sfw bash -c 'curl -sS -x "$HTTP_PROXY" https://127.0.0.1:9/; echo "curl rc=$?"; echo "still here"'
Socket Firewall encountered an unexpected error: Error: connect ECONNREFUSED 127.0.0.1:9
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1637:16)
$ echo $?
0

Neither curl rc=… nor still here is ever printed: the child was killed before curl even returned. The plain-HTTP path handles the equivalent case gracefully (curl -x "$HTTP_PROXY" http://127.0.0.1:9/ returns the "Socket Firewall Connection Required" interstitial and the script continues), so this is specific to the HTTPS CONNECT path.

Expected

A refused upstream connection is a routine client-visible error, not a proxy-fatal one: return 502/504 on the CONNECT, keep the proxy alive, and let the wrapped command handle its own failed request (plain curl without sfw gets Connection refused and the script continues).

Real-world impact

Any wrapped command that spawns a subprocess making HTTPS calls to an endpoint that happens to be down dies this way. We hit it repeatedly with a CLI tool (a headless AI agent) shelled from under sfw uv run …: the agent dials some endpoint that's unreachable in that environment, sfw crashes, and the whole job's process tree is killed ~20s in. Combined with the exit-0 issue, this cost us three consecutive silent overnight CI failures before root-causing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions