windmill-labs/windmill · error
Bad Gateway
Error message
Bad Gateway
What it means
multiplayer/gateway.mjs runs an HTTP proxy in front of per-instance multiplayer servers. Its proxy 'error' handler writes a 502 (if headers were not already sent) and ends the response with 'Bad Gateway'. It means the gateway could not complete the proxied request to the target port.
Source
Thrown at multiplayer/gateway.mjs:69
const { port, path } = resolve(clientReq.url)
const opts = {
hostname: '127.0.0.1',
port,
path,
method: clientReq.method,
headers: clientReq.headers,
}
const proxy = http.request(opts, (proxyRes) => {
clientRes.writeHead(proxyRes.statusCode, proxyRes.headers)
proxyRes.pipe(clientRes, { end: true })
})
proxy.on('error', (err) => {
console.error(`[gateway] HTTP proxy error → :${port}${path}: ${err.message}`)
if (!clientRes.headersSent) {
clientRes.writeHead(502, { 'Content-Type': 'text/plain' })
}
clientRes.end('Bad Gateway')
})
clientReq.pipe(proxy, { end: true })
})
// ---- WebSocket proxy (upgrade) ----
server.on('upgrade', (clientReq, clientSocket, head) => {
const { port, path } = resolve(clientReq.url)
const opts = {
hostname: '127.0.0.1',
port,
path,
method: 'GET',
headers: clientReq.headers,View on GitHub (pinned to e474e8803c)
Solutions
- Check gateway logs for '[gateway] HTTP proxy error' — the message names the target port and path
- Verify the instance server is running and listening on the port the gateway routed to
- Fix or refresh the instance registry/routing entry so it points at a live port
- Retry the request once the instance is healthy
Example fix
// before curl http://gateway/room/1 # instance on :7103 is down → 502 // after docker start multiplayer-instance-7103 # then retry; gateway proxies successfully
Defensive patterns
Strategy: retry
Validate before calling
// before routing to an instance port, probe it
const healthy = await fetch(`http://127.0.0.1:${port}/health`).then(r => r.ok).catch(() => false);
if (!healthy) throw new Error(`multiplayer instance on :${port} is not up`); Try / catch
try {
const res = await fetch(gatewayUrl + path);
if (res.status === 502) {
// instance down; re-check registry and retry after restart
}
} catch (err) { /* network-level failure of the gateway itself */ } Prevention
- Ensure instance servers register with the gateway only after listening
- Add readiness probes so traffic routes only to live ports
- Monitor gateway logs for '[gateway] HTTP proxy error' lines
- Use supervisor/restart policies for instance processes
When it happens
Trigger: A request arrives at the gateway and is proxied to :<port><path>, but the target connection errors: nothing listening on that port, ECONNRESET from the instance server, or the socket closing before a response.
Common situations: Multiplayer instance container/process not started yet or already stopped; stale routing table pointing at a dead port; instance crashing under load and resetting connections; port mapping mismatch between gateway and instances.
Understand the failure class
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Related errors
- Bad Gateway
- Failed to fetch foundation models for AWS Bedrock
- Failed to fetch models for provider ${provider}
- <server error text> || Failed to sign multiplayer session
- no pinned address to connect
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/e661087864725970.
Report an issue: GitHub.