decolua/9router · error
Passthrough error: ${e.message}
Error message
Passthrough error: ${e.message} What it means
In passthroughHttps, the http.request forwarded to the real upstream emits an 'error' on the request object. The handler logs 'Passthrough error: <message>', writes it to the dump, replies 502 Bad Gateway ('Bad Gateway' body) if headers were not sent.
Source
Thrown at src/mitm/server.js:283
forwardRes.pipe(res);
return;
}
const chunks = [];
forwardRes.on("data", chunk => {
if (dumper) dumper.writeChunk(chunk);
if (onResponse) chunks.push(chunk);
res.write(chunk);
});
forwardRes.on("end", () => {
if (dumper) dumper.end();
res.end();
if (onResponse) try { onResponse(Buffer.concat(chunks), forwardRes.headers); } catch { /* ignore */ }
});
});
forwardReq.on("error", (e) => {
err(`Passthrough error: ${e.message}`);
if (dumper) { dumper.writeChunk(`\n[ERROR] ${e.message}\n`); dumper.end(); }
if (!res.headersSent) res.writeHead(502);
res.end("Bad Gateway");
});
if (bodyBuffer.length > 0) forwardReq.write(bodyBuffer);
forwardReq.end();
}
// ── Request handler ───────────────────────────────────────────
const server = https.createServer(sslOptions, async (req, res) => {
try {
if (req.url === "/_mitm_health") {
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({ ok: true, pid: process.pid }));
return;
}View on GitHub (pinned to 90b52e06ff)
Solutions
- Check the underlying code (ENOTFOUND/ECONNREFUSED/ETIMEDOUT) to distinguish DNS vs connectivity vs timeout.
- Fix DNS/hosts entries if the domain resolves to a stale MITM IP.
- Verify outbound internet/VPN connectivity with curl to the target domain.
- Retry on timeout — transient upstream outages surface here.
Example fix
// before getaddrinfo ENOTFOUND api.example.com → 502 Bad Gateway // after # fix hosts/DNS, then verify nslookup api.example.com && curl -I https://api.example.com
Defensive patterns
Strategy: retry
Validate before calling
try {
const addr = await dns.promises.lookup(targetHost);
console.log(`[mitm] ${targetHost} -> ${addr.address}`);
} catch (e) {
return respond502(`DNS failure: ${e.code}`); // ENOTFOUND caught before forwarding
} Type guard
function isDnsError(e) { return e && (e.code === 'ENOTFOUND' || e.code === 'EAI_AGAIN'); }
function isConnRefused(e) { return e && e.code === 'ECONNREFUSED'; } Try / catch
forwardReq.on('error', (e) => {
err(`Passthrough error: ${e.message}`);
if (isDnsError(e) || isConnRefused(e)) {
if (!res.headersSent) res.writeHead(502, { 'Content-Type': 'application/json' });
return res.end(JSON.stringify({ error: { message: e.message, hint: 'check DNS/upstream' } }));
}
if (!res.headersSent) res.writeHead(502);
res.end('Bad Gateway');
}); Prevention
- Verify hosts/DNS overrides resolve to the intended IP before enabling MITM.
- Check network/VPN connectivity when many passthrough requests fail at once.
- Add one retry for transient ETIMEDOUT/ECONNRESET on idempotent requests.
- Clean up MITM DNS entries on shutdown to avoid stale overrides.
When it happens
Trigger: The HTTPS forwarding request fails before a response — DNS ENOTFOUND on the target host, ECONNREFUSED/ETIMEDOUT connecting to port 443, TLS handshake failure, or socket destroyed early.
Common situations: Hosts-file/DNS override pointing the domain at a dead IP; no network/VPN; upstream provider outage; SNI/TLS interception interference from corporate proxies.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- Cursor AgentService request failed: ${error.message}
- MITM server is not running. Start the server first.
- Machine ID is required for Cursor API
- http2 module not available
- HTTP/2 is required for Cursor AgentService (endpoint is h2-o
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/b37d019c84c0fb01.
Report an issue: GitHub.