11 days ago
My backend service container is running and healthy, but no external traffic reaches it.
What works:
Container starts, healthcheck passes (Railway returns 200)
SSH into container → fetch("http://127.0.0.1:8080/health") → 200 OK
Other services in the same project (frontend, landing) work fine
What doesn't work:
Any external request to the Railway-generated *.up.railway.app domain → timeout (no response, not even a 502)
Custom domain → same timeout
What I've tried:
Multiple redeploys (CLI + dashboard)
Deleted service and recreated from scratch → same issue on the new service
Changed region
No code changes same code was working for 18h before the issue started
5 Replies
11 days ago
Hey, make sure the correct port is binded in railway as in your app. In this case, make sure your app is on port 8080 (or whatever you prefer) and in the dashboard, in the public network, make sure that the service also has that same port configured. Also make sure the app is listening to 0.0.0.0.
xmrafonso
Hey, make sure the correct port is binded in railway as in your app. In this case, make sure your app is on port 8080 (or whatever you prefer) and in the dashboard, in the public network, make sure that the service also has that same port configured. Also make sure the app is listening to 0.0.0.0.
11 days ago
Thanks for the suggestion. I checked both:
Port: I set the port explicitly to 8080 on the Railway domain (railway domain -p 8080). The app listens on PORT=8080 which Railway auto-injects.
Binding: I updated my app to explicitly bind to 0.0.0.0 (it was defaulting to :: IPv6 via Bun.serve). I can confirm via SSH that the server now listens on IPv4:
/proc/net/tcp:
0: 00000000:1F90 00000000:0000 0A → 0.0.0.0:8080 LISTEN ✓
I also see active TCP connections from Railway's internal network (100.0.64.x), so the healthcheck and internal probes reach the container. But external traffic via the *.up.railway.app domain still times out no request ever hits the app logs.
vinceduong
Thanks for the suggestion. I checked both:Port: I set the port explicitly to 8080 on the Railway domain (railway domain -p 8080). The app listens on PORT=8080 which Railway auto-injects.Binding: I updated my app to explicitly bind to 0.0.0.0 (it was defaulting to :: IPv6 via Bun.serve). I can confirm via SSH that the server now listens on IPv4:/proc/net/tcp:0: 00000000:1F90 00000000:0000 0A → 0.0.0.0:8080 LISTEN ✓I also see active TCP connections from Railway's internal network (100.0.64.x), so the healthcheck and internal probes reach the container. But external traffic via the *.up.railway.app domain still times out no request ever hits the app logs.
11 days ago
Verify there is an actual generated Railway domain listed for this service. ..if its genrated do either nslookup or dig your service url..what are you getting when you do curl -v ..your URL
dharmateja
Verify there is an actual generated Railway domain listed for this service. ..if its genrated do either nslookup or dig your service url..what are you getting when you do curl -v ..your URL
11 days ago
Yes, the Railway domain is generated and listed:
$ railway domain -s backend --json
{
"domains": [
"https://backend-production-cef0.up.railway.app",
]
}
DNS resolves fine:
$ dig backend-production-cef0.up.railway.app +short
151.101.2.15
curl -v output — TLS handshake succeeds through Fastly, HTTP/2 request is sent, then it hangs until timeout with zero bytes received:
$ curl -sv --max-time 10 https://backend-production-cef0.up.railway.app/health
* Connected to backend-production-cef0.up.railway.app (151.101.2.15) port 443
* SSL connection using TLSv1.3
Server certificate: CN=.up.railway.app (Certainly Intermediate R1)
* using HTTP/2
> GET /health HTTP/2
> Host: backend-production-cef0.up.railway.app
> User-Agent: curl/8.7.1
> Accept: /
>
* Operation timed out after 10002 milliseconds with 0 bytes received
No response at all not a 502, not a 404, just silence. The request reaches Fastly but never gets forwarded to the container.
just confirmed again via SSH — the server responds correctly from inside the container:
$ railway ssh -s backend
$ bun -e 'const r = await fetch("http://127.0.0.1:8080/health"); console.log(r.status, await r.text())'
200 {"status":"ok"}
Response includes proper headers (content-type, content-length, CORS). Also works on 0.0.0.0:8080. The app is healthy — it's the path between the Fastly edge and the container that's broken.
10 days ago
Resolved! Root cause was the Bun version used by Railpack during the build.
My package.json had "packageManager": "bun@1.0.23". Railpack uses this to install Bun in the container. Containers built with Bun 1.0.23 have a networking issue where the Metal Edge proxy cannot route public traffic to them (internal healthchecks work fine since they use a different path).
How I diagnosed it:
Created a new service test-backend and deployed via railway up (direct upload, no GitHub integration) — it worked publicly
Linked the same service to GitHub repo (config-as-code) public traffic broke again
Compared the two builds: railway up used Bun 1.3.9 (latest), GitHub deploy used Bun 1.0.23 (from packageManager field)
Deployed again via railway up with "packageManager": "bun@1.3.9" in the deploy package worked
Deployed via railway up without it (Railpack cached Bun 1.0.23) broke again
Fix: Bumped "packageManager": "bun@1.3.9" in package.json, regenerated lockfile, pushed. GitHub deploy now works with public routing.
TL;DR: If you're using Bun with Railpack and getting this symptom (healthy container, public timeout, zero bytes from edge), check your Bun version. Bun 1.0.23 produces containers that the Metal Edge proxy can't route to. Upgrading to 1.3.9 fixed it.