Bun 1.4.3 ERR_PROXY_TUNNEL: is it a Sume error or your proxy?

Bun 1.4.3 rejects fetch with ERR_PROXY_TUNNEL on a failed CONNECT. A Sume error always carries error.request_id; use it to tell the two apart.

4 min readSume
All posts

If a Bun fetch to api.sume.com rejects with ERR_PROXY_TUNNEL, the failure happened at your proxy, not at Sume. Sume's own errors always come back as a JSON body with error.code and error.request_id, so the presence of a request_id is the cheapest way to separate a Sume refusal from a network-path failure.

What Bun 1.4.3 changed

The Bun v1.4.3 release notes (read 2026-10-10) say a non-2xx response to a proxy CONNECT now rejects fetch with ERR_PROXY_TUNNEL, carrying the status and headers. They also say NO_PROXY now accepts wildcards, CIDR blocks, bare IPv6 and host:port.

Bun v1.4.3 proxy changes (read 2026-10-10)
BehaviorBefore / after
Non-2xx CONNECT responseRejects with ERR_PROXY_TUNNEL, with status and headers attached
NO_PROXY syntaxAccepts wildcards, CIDR blocks, bare IPv6, host:port

What a Sume error looks like

The API reference documents one error envelope with the request id inside error, and the errors page lists the codes. A proxy that refuses the tunnel never reaches Sume, so no envelope exists.

Who produced the failure (Sume docs, errors and rate limits)
What you seeSourceSafe next step
JSON with error.code and error.request_idSumeBranch on code: 402 add funds, 429 back off with retry-after, 400 fix the request
Rejection with no response, such as ERR_PROXY_TUNNELYour network pathFix proxy or NO_PROXY. If you sent a paid submit, retry only with the same Idempotency-Key
HTML or non-Sume JSON body with an HTTP statusGateway or proxy in betweenTreat as transport; do not read it as a Sume code

A classifier you can paste

This wrapper returns one of three kinds. It only trusts a response as Sume's when error.request_id is present.

export async function sumeFetch(url, init) {
  let res;
  try {
    res = await fetch(url, init);
  } catch (e) {
    return { kind: "transport", code: e.code ?? e.name };
  }
  const body = await res.json().catch(() => null);
  const err = body?.error;
  if (err?.request_id) {
    return { kind: "sume", status: res.status, code: err.code, requestId: err.request_id };
  }
  return { kind: "intermediary", status: res.status };
}

Retry rule for paid submits

A transport failure on a submit leaves you not knowing whether the job was created. Sume's docs say to send an Idempotency-Key on paid submits so a retry returns the original job instead of billing a second one. Reuse the same key for the exact retry, and use a new key only for new work.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume