2 months ago
Hi!
My Django backend service has custom domain *.fleetdata.pro (active). DNS is on Cloudflare; all tenant subdomains resolve identically:
demo / hermes / tva / public / zzztest999
→ *.fleetdata.pro
→ ujs9yjp6.up.railway.app
→ 69.46.46.66
The problem is that Railway's edge only routes some hostnames to our Django app, even when they hit the same edge IP.
What works:
hermes.fleetdata.pro — GET / returns 302 to login; POST /api/token/pair returns 401 JSON. Request reaches Django (we see x-frame-options: DENY).
tva.fleetdata.pro — same as hermes.
public.fleetdata.pro — GET / returns a Django HTML 404 page; POST /api/companies/resolve-tenant/ returns 200 JSON. Request reaches Django.
What does not work:
demo.fleetdata.pro — GET / returns 404 with an empty body (0 bytes). POST /api/token/pair also returns 404 with an empty body. No Django headers (x-frame-options is missing). Only Railway edge headers are present (server: railway-hikari, x-railway-edge, x-hikari-trace).
zzztest999.fleetdata.pro (random, never registered) — same empty edge 404 as demo.
Same DNS, same edge, different result per hostname — so Railway's edge is accepting the connection but not forwarding "demo" to my app.
We can reproduce it by sending requests to the same IP and only changing the Host header:
IP=69.46.46.66
curl -sI --resolve demo.fleetdata.pro:443:$IP https://demo.fleetdata.pro/
-> 404, empty body, no Django response
curl -sI --resolve hermes.fleetdata.pro:443:$IP https://hermes.fleetdata.pro/
#-> 302 to /accounts/login/, Django response
Why does *.fleetdata.pro not route all subdomains (e.g. demo, random hosts), while hermes, tva, and public work on the same edge IP? What is the correct way to register new tenant subdomains so they route reliably?
Note: I might have had individual tenant subdomains on railway backend at some point in the past before the wildcard domain.
2 Replies
2 months 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 • 3 months ago
2 months ago
Thanks, masteraiwork10-cyber — your diagnosis matched what I noticed. The *.fleetdata.pro wildcard on my Django Backend is verified (CNAME + _acme-challenge + _railway-verify TXT in Cloudflare) but does not route new subdomains. hermes/tva/public reach Django; demo and random hosts (zzztest999) got empty edge 404s on the same IP until explicitly registered.
Option 1: I had no individual subdomain entries visible in Railway Networking — only the wildcard. So there was nothing to delete. hermes/tva/public still routed (likely grandfathered).
Option 2: This worked. I registered demo.fleetdata.pro explicitly on the backend with CNAME + _railway-verify.demo TXT in Cloudflare. After Railway showed Active, demo returned 302 + Django 401 JSON on /api/token/pair.
It's still unclear why a fully verified *.fleetdata.pro wildcard does NOT route all subdomains, requiring explicit per-host registration for each new tenant?
13 days ago
Your Option 2 result is the decisive test: DNS, TLS and Django are healthy. The empty 404 with Railway/Hikari headers means the edge had no usable host route for demo; adding an exact demo.fleetdata.pro custom-domain object created that route and immediately restored the Django response.
That is a workaround, not the expected wildcard model. Railway's current domain documentation says a verified *.fleetdata.pro wildcard supports arbitrary first-level subdomains. The networking limits also say an exact subdomain and its wildcard cannot overlap unless they are owned by the same service. Given the history you mentioned, the likely discriminator is an old exact-host object attached to another/deleted service or an orphaned edge route that shadows the wildcard even though it is no longer visible on the Django service's Networking panel.
I would resolve it without touching the healthy app or wildcard DNS:
- Inventory domain objects across the whole project/environment, not only the current service panel. Use
railway domain list --service <service> --environment <environment>for each relevant service and the Public API's custom-domain list/status operations. Record domain ID, owning service ID, target port and certificate/DNS status for*.fleetdata.pro,demo,hermes,tvaandpublic. - If an exact hostname is attached to the wrong/deleted service, delete only that exact custom-domain object there. Do not remove the wildcard, Cloudflare records or a healthy exact route first. Wait for the change to show applied/Active.
- Test a brand-new hostname that has never been registered, for example
wildcard-probe-20260808.fleetdata.pro, and captureX-Railway-Request-Id,X-Railway-Edge, status and response headers. A Django response proves the wildcard route is working; an empty Hikari 404 proves the wildcard object is still absent from the edge host-route table. - If the API lists only the active wildcard on the correct service and the fresh hostname still returns the empty edge 404, this needs Railway staff to rebuild/remove the stale route index. Send the wildcard domain ID, service/environment IDs and one paired working/failing request ID. The exact-host registration is a safe temporary mitigation, but you should not need one Railway domain object per tenant.
Keep the Cloudflare wildcard CNAME, verification TXT and unproxied _acme-challenge record exactly as Railway generated them. Current docs also require Universal SSL and Full SSL/TLS for first-level Cloudflare wildcards. Since the same wildcard certificate already serves both working and failing names, certificate issuance is not the remaining fault here.
Official references: