2 months ago
Anyone got similar problems?
Our production x402 payment API service on Railway's Metal Edge network is returning 502 Bad Gateway for specific API paths, while identical requests to other paths work correctly. The blocking pattern is very specific and appears to be based on path keywords.
Domain:https://emc2ai.io
Service URL:https://eliza-v2-live.up.railway.app
| Path Pattern | Status | Notes |
|--------------|--------|-------|
| /x402/bitquery/whaleintel | 502 BLOCKED | Base path blocked |
| /x402/bitquery/whaleintel/raw | 402 ✓ | Only working suffix |
| /x402/bitquery/whaleintel/analyzed | 502 BLOCKED | Also blocked |
| /x402/bitquery/whaleintel/full | 502 BLOCKED | Also blocked |
| /x402/bitquery/investment-report | 402 ✓ | Unaffected endpoint |
The blocked path returns 2.5x faster with only 157 bytes (nginx error page). This proves the 502 is returned by Metal Edge BEFORE the request reaches our application.
This proves the app IS running and receiving requests. The 502 is being injected by Metal Edge for specific registered paths.
The blocking has these characteristics:
Path-specific: Only 13 specific endpoint patterns are blocked
Suffix-specific: Only
/rawbypasses;/analyzedand/fullare blockedMethod-specific: OPTIONS allowed, all other methods blocked
Accept-header aware:
text/htmlpasses,application/jsonblockedUnregistered paths pass: Only registered API paths are blocked
This appears to be a security filter matching keyword patterns in paths combined with API request characteristics.
Can you investigate why Metal Edge blocks these specific path patterns?
Is there a way to whitelist our
/x402/bitquery/*paths?Why does
/rawpass but/analyzedand/fullget blocked? They're all the same handler returning the same response format.Can we disable path-based filtering for our service?
13 Replies
2 months ago
Is there a difference in the response types for these endpoints?
2 months ago
The only difference is the JSON payload structure, not the response type:
// /raw variant - simpler payload
{
status: 'completed',
service: { variant: 'raw' },
result: { /* data */ }
}
// /analyzed or /full variant - includes AI analysis
{
status: 'completed',
service: { variant: 'analyzed' },
result: { /* data */ },
analysis: {
summary: '…',
insights: […],
signals: {…}
}
}
2 months ago
All endpoints use identical handler returning Content-Type: application/json; charset=utf-8.
Live proof:
┌────────────────────┬────────┬─────────────────────────┐
│ Endpoint │ Status │ Content-Type │
├────────────────────┼────────┼─────────────────────────┤
│ /investment-report │ 402 ✅ │ application/json │
├────────────────────┼────────┼─────────────────────────┤
│ /whaleintel │ 502 ❌ │ text/html (nginx error) │
├────────────────────┼────────┼─────────────────────────┤
│ /whaleintel/raw │ 502 ❌ │ text/html (nginx error) │
├────────────────────┼────────┼─────────────────────────┤
│ /tokensniping/raw │ 402 ✅ │ application/json │
└────────────────────┴────────┴─────────────────────────┘
The text/html on blocked endpoints is nginx's 502 error page - request never reaches our app.
Critical: tokensniping/raw and whaleintel/raw use identical code, headers, and response format. Only difference is the path keyword. Both are POST + application/json.
This proves blocking is purely path-pattern based at Metal Edge level.
2 months ago
We do not use nginx to forward traffic for the metal edge.
2 months ago
Both endpoints, working (investment-report) and blocked (whaleintel) requests show identical headers:
server: cloudflare
x-proxy: cf-worker
x-railway-edge: railway/europe-west4-drams3a
Our app only returns JSON via jsonResponse() - never HTML. The nginx/1.22.1 502 HTML page comes from somewhere in Railway's infra before reaching our container. All 25 endpoints use identical code paths with no path-specific filtering.
Is there a way to check Railway logs to see if these requests are even reaching our container?
2 months ago
Check the HTTP logs.
2 months ago
Either way, we are not blocking these URL patterns. This is something with Cloudflare or with your application.
2 months ago
hi @chuxo
I faced similar difficulties recently while deploying my project.
For me, I found that the port which was being injected on Railway (process.env.PORT) was not exposed.
You can specifically expose one PORT on the your application from network settings of app.
It might have messed it up earlier but this is what fixed the issue for me.
Added a screenshot too.
Attachments
2 months ago
502 Issue - Status Update
### Root Cause: Railway Edge Layer (NOT ports, NOT Cloudflare, NOT app)
Evidence:
Port configuration verified correct (8080 → nginx → 3402)
Direct Railway access shows same 502 (bypasses Cloudflare)
Same upstream, same Bun server - partial path failures The issue is likely in Railway's infrastructure, likely at the Metal Edge layer, despite their claim of not blocking these patterns. The nginx/1.22.1 error might be Railway's default error page format.
2 months ago
PROOF: Our application returns 402, client receives 502
Log evidence from 2026-01-14 20:31:23 UTC:
REQUEST: POST /x402/bitquery/whaleintel
APP LOG: "Request completed, status: 402"
CLIENT: Received 502 Bad Gateway (nginx/1.22.1)
2 months ago
^
2 months ago
Hi Railway team,
I wanted to follow up and apologize for the confusion regarding the 502 errors we reported.
After extensive debugging with detailed header logging, we discovered the issue was caused by our own nginx configuration, not Railway's infrastructure.
Root cause: Our nginx proxybuffersize was set to the default 4KB, but our x402 payment protocol headers (containing base64-encoded payment challenges with outputSchema definitions) were exceeding 4KB for certain endpoints (~4.3KB).
Fix: We increased proxybuffersize to 16KB in our nginx config. All endpoints now work correctly.
Thank you for your patience and for confirming that Railway doesn't use nginx for Metal Edge traffic - that key insight helped us redirect our investigation to the right place.
Apologies again for the misdirected investigation. Railway's infrastructure is working exactly as expected.
2 months ago
Glad you found the solution!
Status changed to Solved brody • about 2 months ago