Regression: all local TCP listeners denied ("bind: permission denied") since July 13 — affects two projects
Anonymous
PROOP

a month ago

Since 2026-07-13 our containers cannot open ANY local TCP listener beyond the app's $PORT — every listen() fails with "bind: permission denied", regardless of address (0.0.0.0 or 127.0.0.1) or port (tried 6462 and 8080). This worked for weeks until today.

Context: we run a userspace WireGuard proxy (wireproxy) exposing a local TCP forward to an on-prem API. Outbound UDP works — the WireGuard handshake completes every time. Only the local listen() is denied, before any traffic leaves the container.

Evidence:

  • Project: db85afea-1ea3-4359-9850-979e4730480c (environment: production)
  • Service: rezerwacje-7sun (c8c7c255-d9db-4f1e-af15-0069b9820d29)
  • Deployments: 81a97cba-c615-42c1-8547-ce261b9fb419 (first failure 15:41 UTC) and 64375ea2-6372-4352-9c0e-3d236d33bf58 (still failing 16:09 UTC)
  • Exact log line: listen tcp 0.0.0.0:6462: bind: permission denied
  • A second, independent project in this account hit the same regression today (same error, different ports).

Timing correlates with the July 13 Legacy Static IP migration deadline. Was a sandbox/network policy change rolled out on 2026-07-13? Is this intentional or a regression? If intentional, what is the supported way to run local TCP forwards going forward?

$20 Bounty

4 Replies

Railway
BOT

a month ago

This thread has been opened as a public bounty so the community can help solve it. The thread and any further activity are now visible to everyone.

Status changed to Open Railway about 1 month ago


spjoes
HOBBY

a month ago

Hey! I don't think this is a setup issue. It MAY be something Railway changed on their side.

"bind: permission denied" normally only happens on ports below 1024. You're using 6462 and 8080, which should never be blocked (so Railway's platform could be blocking your app from opening any local port except the main $PORT it gives you). That's why switching ports or addresses doesn't help. You mentioned your outbound WireGuard traffic still works and it's only the extra local listener that's denied.

You also mentioned it started today (July 13/the Legacy Static IP migration day) and hit a second project the same day, so this looks like a possible side effect of that networking change.

Something to check though: does binding to exactly $PORT work while every other port fails? If so, that's a good example to mention.

I believe this one needs a Railway employee since only they can say if it's intentional and what the supported way to run a local TCP forward is now.


Anonymous
PROOP

a month ago

We ran the experiment you suggested — the result is sharper than "$PORT-only":

At boot, BEFORE the app started, a Node.js probe successfully bound 0.0.0.0:8080 ($PORT), 0.0.0.0:8081 AND 0.0.0.0:6462 — all OK. Seconds later in the same container, wireproxy (a Go binary, child of the same shell, same user) got: "listen tcp 0.0.0.0:6462: bind: permission denied". Go's UDP bind works fine (the WireGuard handshake completes every time).

So it's not port-based at all: the sandbox denies TCP listen() specifically to the Go binary while Node.js can bind any port. Looks like a syscall-filter (gVisor/seccomp?) regression affecting Go's listener path. Repro deployment: 9bce15c… probe logs are tagged [bind-probe] in deployment 64375ea2→ successor from 2026-07-13 ~16:29 UTC, service c8c7c255-d9db-4f1e-af15-0069b9820d29.


Anonymous
PROOP

a month ago

Update: we also tested alternating the bind address — Go's listen() is denied on BOTH 0.0.0.0 and 127.0.0.1 (any port). Node.js binds all of them fine in the same container. So the filter is runtime/binary-specific, not address- or port-based.


ilia-ilin-jiji
FREE

25 days ago

Hitting the exact same issue described above: any net.Listen/net.ListenTCP call from a Go binary in our container fails with bind: permission denied, regardless of address (0.0.0.0) or port number — including Railway's own injected $PORT (tested explicitly, still fails).

To isolate it, I ran a control test in the same project: a plain redis:8.2.1 service (not Go) binds its port fine on the same infrastructure. Our Go-based service (a WireGuard userspace proxy, wireproxy) fails to bind any port every time, even after EXPOSE-ing it and trying several arbitrary port numbers. This matches the OP's finding that it's specific to Go's listener path, not port/address-related.

Deploy is a custom Dockerfile (Debian bookworm-slim based), no unusual capabilities requested, runs as root, no special socket options in the code path (verified against upstream source — plain net.ListenTCP, no SO_REUSEPORT/IP_TRANSPARENT/custom Control func).

Any update on root cause / ETA? Happy to share full logs/service ID if useful for debugging.


Welcome!

Sign in to your Railway account to join the conversation.

Loading...