21 days ago
I've attached a custom domain to a service, and Railway issued a valid Let's Encrypt certificate for it. However, requests to the custom domain consistently return 502, while requests to the auto-generated domain on the same service (same deployment, same container) return 200.
Setup:
Custom domain attached via CLI
DNS verified (CNAME resolves correctly, consistent across multiple resolvers, no proxying)
Certificate valid (Railway-issued, TLS handshake completes)
Container healthy and listening on the configured port
Service config shows the generated domain in serviceDomains, but the custom domain is absent
HTTP logs show:
Custom domain requests: "error":"connection refused" — edge cannot reach the container
Generated domain requests: successful 200 responses
Both domains point to the same deployment instance
Timeline:
Persistent for ~90 minutes
No intermittency across multiple polling attempts
Removed and re-added the domain; issue persists
Question: Is this a known issue with custom domain routing on the edge? The domain attachment UI accepted the custom domain and issued a cert, but the edge routing doesn't appear to include it. Should the custom domain appear in serviceDomains configuration, or is the routing handled separately?
8 Replies
Status changed to Awaiting Railway Response Railway • 21 days ago
21 days ago
Update — additional evidence narrowing this to edge host routing
Further testing since posting. Summary: the fault follows the hostname, not the service, deployment, or edge node.
(Custom hostnames redacted below as and www.; happy to DM the exact values. Project 4f938935-4119-4a4e-8dff-19242fc1ce4d.)
- Reproduced on a brand-new service. I created a second service in the same project, deployed the same image, and attached a custom hostname to it. Identical result — 502 on the custom hostname, 200 on that service's generated domain. Rules out per-service state.
Three custom hostnames affected across two services:
┌─────────────────────────────────────┬───────────────────────────┬────────┐
│ Hostname │ Service │ Result │
├─────────────────────────────────────┼───────────────────────────┼────────┤
│ │ service A │ 502 │
├─────────────────────────────────────┼───────────────────────────┼────────┤
│ www. │ service A │ 502 │
├─────────────────────────────────────┼───────────────────────────┼────────┤
│ www. │ service B (created fresh) │ 502 │
├─────────────────────────────────────┼───────────────────────────┼────────┤
│ service A generated .up.railway.app │ service A │ 200 │
├─────────────────────────────────────┼───────────────────────────┼────────┤
│ service B generated .up.railway.app │ service B │ 200 │
└─────────────────────────────────────┴───────────────────────────┴────────┘
- Not an unhealthy edge node. Forcing specific edge IPs with curl --resolve:
via 69.46.46.111 → 200
via 69.46.46.64 → 200
www. via 69.46.46.64 → 502
www. via 69.46.46.84 → 502
Every edge node serves the generated hostname correctly; every edge node fails the custom hostname. Global to the hostname, not localised to a server.
-
The container never receives the requests. The service is nginx serving static files with no upstream — architecturally incapable of returning 502; it can only return 200 or 404. Its access log contains no 502s and no entries corresponding to the failing requests. With the connection refused in Railway's own HTTP logs, the request terminates at the edge before reaching the container.
-
Not account-wide. Four custom domains on other projects in this account all route correctly — they return 200/404 from the application, never 502. Custom-domain routing works elsewhere on the account; it fails for every hostname in this project.
Ruled out: Cloudflare proxying (grey-clouded; DNS resolves to Railway edge IPs consistently from 1.1.1.1 / 8.8.8.8 / 9.9.9.9), target port (tested 80 and 8080 — the generated domain served correctly through both), certificate issuance (valid Railway-issued certs for all three hostnames), wrong service attachment, remove/re-add ordering (three attempts), service-level state (fresh service), and edge-node health.
Refined question: certificate provisioning succeeds for these hostnames while routing does not, which suggests the two paths diverge. Is the host→service mapping populated separately from cert issuance, and can it get stuck in a state that removing and re-adding the domain doesn't clear? That would explain why every remediation available to me has no effect.
Still 502 as of 2026-07-31 10:01 UTC
21 days ago
Your diagnosis is correct - certificate issuance and edge route registration are separate paths, and the route installation failed silently for the custom domains in this project. We've triggered a routing repair on the affected service, which reinstalls the host-to-service mapping at the edge. This may take a few minutes to propagate. The apex domain (coachds.com) appears to have been removed during your testing, so only www.coachds.com was repaired - if you re-add the apex, let us know and we can re-run the repair.
Status changed to Awaiting User Response Railway • 21 days ago
Status changed to Solved sam-a • 21 days ago
sam-a
Your diagnosis is correct - certificate issuance and edge route registration are separate paths, and the route installation failed silently for the custom domains in this project. We've triggered a routing repair on the affected service, which reinstalls the host-to-service mapping at the edge. This may take a few minutes to propagate. The apex domain (`coachds.com`) appears to have been removed during your testing, so only `www.coachds.com` was repaired - if you re-add the apex, let us know and we can re-run the repair.
21 days ago
Thanks — that confirms it exactly, and matches what the evidence pointed to.
Still 502 as of 12:38 UTC, ~2 hours after the repair, so it's past the propagation window.
One thing that may explain it: www.coachds.com moved between services during my testing. It was on c0dd09bb-95fb-469d-889c-77d33e5bbec8 when I opened the ticket, but it's now attached to a service I created afterwards while isolating the fault:
www.coachds.com → 63b54eb7-6b43-4e9d-bb93-ecc6143d80f6 ← current, still 502
If the repair ran against c0dd09bb…, it would have reinstalled the mapping on a service the domain is no longer attached to. Could you re-run it against 63b54eb7-6b43-4e9d-bb93-ecc6143d80f6?
That service's generated domain (web-production-650ac.up.railway.app) is serving 200 normally, so the service itself is healthy — only the custom hostname's route is missing.
I've left the apex off for now. Once www is confirmed working I'll re-add coachds.com to the same service and come back for the second repair, rather than have you run it twice.
Status changed to Awaiting Railway Response Railway • 21 days ago
21 days ago
Good catch - the earlier repair targeted the service the domain was originally on, not the one it moved to during your testing. We've triggered a routing repair against the current service (63b54eb7). This should propagate within a few minutes. Once www.coachds.com is serving correctly, re-add the apex and reply here so we can run the same repair for it.
Status changed to Awaiting User Response Railway • 21 days ago
21 days ago
Make sure the port your application is listening to is the same port your URL is mapped to.
Status changed to Awaiting Railway Response Railway • 21 days ago
Status changed to Awaiting User Response 0x5b62656e5d • 21 days ago
20 days ago
Resolved. The issue was a target port mismatch, not Railway routing.
Thanks to everyone who took the time to help troubleshoot and offer suggestions. The discussion helped narrow the problem down, and hopefully this summary saves someone else a few hours of debugging.
Just FYI - The container was listening on the runtime-injected port (PORT=8080), but the custom domain was configured to use target port 80.
Container: 0.0.0.0:8080
www....com target port 80 → 502
web-production-....up.railway.app default routing → 200Because the target port is configured per custom domain, two hostnames can point to the same service and container while behaving differently. Changing the custom domain's target port to 8080 immediately restored service—no redeploy required.
One useful observation for anyone troubleshooting this:
| Response | Meaning |
| ------------------------------------------------- | ---------------------------------------------------------------------------------- |
| 404 {"message":"Application not found"} | No host-to-service mapping (routing issue). |
| 502 {"message":"Application failed to respond"} | Route exists, but the edge cannot connect to the container. Check the target port. |
Both responses include x-railway-fallback: true, so that header alone isn't enough to distinguish the cause—the JSON response is.
The apex domain has also been re-added with target port 8080 and is waiting for certificate issuance.
Status changed to Awaiting Railway Response Railway • 20 days ago
Status changed to Solved fonafowokan • 20 days ago
fonafowokan
Resolved. The issue was a target port mismatch, not Railway routing. Thanks to everyone who took the time to help troubleshoot and offer suggestions. The discussion helped narrow the problem down, and hopefully this summary saves someone else a few hours of debugging. Just FYI - The container was listening on the runtime-injected port (`PORT=8080`), but the custom domain was configured to use target port **80**. ```text Container: 0.0.0.0:8080 www....com target port 80 → 502 web-production-....up.railway.app default routing → 200 ``` Because the target port is configured per custom domain, two hostnames can point to the same service and container while behaving differently. Changing the custom domain's target port to **8080** immediately restored service—no redeploy required. One useful observation for anyone troubleshooting this: | Response | Meaning | | ------------------------------------------------- | ---------------------------------------------------------------------------------- | | `404 {"message":"Application not found"}` | No host-to-service mapping (routing issue). | | `502 {"message":"Application failed to respond"}` | Route exists, but the edge cannot connect to the container. Check the target port. | Both responses include `x-railway-fallback: true`, so that header alone isn't enough to distinguish the cause—the JSON response is. The apex domain has also been re-added with target port **8080** and is waiting for certificate issuance.
20 days ago
One correction to my last update: the apex isn't waiting on certificate issuance—it failed with:
Failed to issue TLS certificate: Let's Encrypt rate limit reached... cannot be automatically retried.
One thing worth calling out: every time you attach a domain, Railway requests a certificate. Let's Encrypt allows only five duplicate certificates for the same hostname set within a rolling seven-day window. While tracking down the port issue, I removed and re-added the apex enough times to hit that limit.
So everything is configured correctly now, but the apex still can't get a certificate until the rate limit resets. If you're troubleshooting a custom domain, it's worth fixing the underlying issue before repeatedly reattaching the domain, or you can end up solving the problem but still waiting days for TLS.
Two questions for the Railway team, if they're easy to answer:
- Can the UI show the certificate rate-limit reset time? The ACME response should include it, but right now it just says "rate limit reached."
- Is there any option to use another ACME CA (for example, ZeroSSL or Google Trust) when this happens, or is Let's Encrypt the only issuer?
No rush—www is serving correctly and that's the canonical hostname.
Thanks again to everyone who helped.
Status changed to Awaiting Railway Response Railway • 20 days ago
20 days ago
The rate limit resets on a rolling seven-day window from each certificate issuance, so the earliest slot will open once your oldest issuance ages past seven days. We don't currently surface the reset timestamp in the UI - that's a fair feature suggestion.
Let's Encrypt is the only issuer we use. There's no option to switch to ZeroSSL or another CA.
Status changed to Awaiting User Response Railway • 20 days ago
13 days ago
This thread has been marked as solved automatically due to a lack of recent activity. Please re-open this thread or create a new one if you require further assistance. Thank you!
Status changed to Solved Railway • 13 days ago