a month ago
Region: railway/us-west2
Domain: cwgt-ai-bot-production.up.railway.app -> port 3000
Every path on the public domain (/, /agent/health, /tv-webhook, and any random path) returns HTTP 403 with an empty body, server: railway-hikari, from BOTH residential and datacenter client IPs. The container itself is healthy - outbound Telegram long-polling works and the bot responds to commands. This is blocking all inbound HTTP, including our live TradingView webhooks, so production signal traffic is currently down.
Already checked / ruled out:
- No Edge Rules configured (Edge Rules panel shows "No edge rules configured")
- Under Attack Mode is OFF
- No IP allowlist / WAF / bot-blocking setting exists in service or project settings
- Private Networking and Outbound IPv6 are normal/unrelated
- Domain was deleted and regenerated - no change
- Domain -> service -> port 3000 mapping is correct; x-railway-upstream-zone resolves to railway/us-west2
- Started around 2026-08-25 UTC with no settings change on our side
Sample x-railway-request-id values (edge den1):
- PdLi724tShWBpel39I3ezw
- utrp5eRHTtWXcFHO2h0iww
- 6aMaRz75Qqe58cIcnPRhug
- Hcb2MHjVRMyO8bUgn6XIxQ
Please clear whatever edge/abuse policy is denying this services public traffic.
2 Replies
Status changed to Awaiting Railway Response Railway • about 1 month ago
a month ago
the 403s are generated are generated by your application, not Railway
You may want to debug it on your side
Status changed to Awaiting User Response Railway • about 1 month ago
a month ago
This thread has been opened as a bounty so the community can help solve it.
Status changed to Open Railway • about 1 month ago
15 days ago
Hi @waby88,
As Angelo confirmed, this 403 is being returned by your application inside the container, not Railway.
The reason you see server: railway-hikari is simply because Railway's edge proxy attaches that header to all outgoing responses, including responses generated by your Node/Python code. And Telegram long-polling works because polling makes outbound requests to api.telegram.org rather than listening on inbound port 3000.
Because every single path (/, /agent/health, /tv-webhook, and random URLs) returns a 403 with an empty body, the rejection is being triggered by a global middleware mounted before your route handlers.
Here are the 3 exact things in your bot codebase causing this:
1. TradingView Auth Middleware Mounted Globally (Check this first!)
If you have a passphrase or token check for your TradingView webhooks, verify that you didn't mount it globally with app.use():
// ❌ WRONG (Blocks /, /agent/health, and all paths with 403):
app.use((req, res, next) => {
if (req.body?.passphrase !== process.env.TV_PASSPHRASE) {
return res.sendStatus(403); // Returns empty body 403
}
next();
});
// CORRECT (Scoped ONLY to the webhook route):
app.post('/tv-webhook', verifyPassphrase, (req, res) => { ... });
// Add this logger at the very top of your Express/FastAPI app before any other middleware:
app.use((req, res, next) => {
console.log(`[INCOMING] ${req.method} ${req.path} - Headers:`, req.headers);
next();
});