A 500 Internal Server Error through a proxy most likely came from the website. The HTTP standard gives a proxy its own code for a bad answer from the site, 502 Bad Gateway. In our test, none of 12 free proxies answered 500 for a site that cannot exist. For HTTPS you can be sure. A 500 in reply to the proxy's tunnel request is the proxy's, and anything after the tunnel opens comes from the site. If the site sent it, only the site can fix it. If the proxy or a gateway sent it, change the proxy or contact whoever runs it.
We tested this on 11 October 2026 on our own server. We used a stub site and a stub proxy, 12 free proxies from our list, and our own gateway.
Who sent the 500?
| Who sent it | The sign | What to do |
|---|---|---|
| The website | The HTTPS tunnel opened first, or the body is the site's own; the same request fails without the proxy | Wait, retry later and report it to the site |
| The proxy | A 500 in reply to CONNECT: curl says "CONNECT tunnel failed, response 500". Or a proxy error page, such as Squid's "The requested URL could not be retrieved" | Use another proxy, or none |
| The HProxy gateway | Its own documented codes: 407, 403, 464 to 467 and 568. Any other 5xx is a gateway error | Retry with backoff. If it persists, send support the time and the line's port |
| An API backend in a chat app | "Proxy error 500" in Janitor AI and similar apps, where the proxy is the model's API | Retry after a short wait, or switch model or provider |
A 500 itself only says that the server that answered hit an unexpected condition. The status does not say which server in the chain that was. The signs above do.
If the site uses HTTPS
An HTTPS request through a proxy starts with a CONNECT request to the proxy. The HTTP standard is strict about the reply. Any 2xx means the tunnel is open, and "data received after that header section is from the server identified by the request target". Any other reply means "the tunnel has not yet been formed".
So a 500 in reply to CONNECT is the proxy's own. curl names it exactly. Current versions print "CONNECT tunnel failed, response 500". Older ones, such as 7.68.0, printed "Received HTTP code 500 from proxy after CONNECT". Both end with exit code 56, which curl defines as "Failure with receiving network data".
A 500 that arrives after the tunnel opened is the site's. The proxy only passes encrypted bytes at that point, so it cannot write the site's answer.
If the site uses plain HTTP
Plain HTTP has no tunnel step, so you read the answer itself. Three things help, and two of them often fail.
- The Via header. The standard says a proxy "MUST send an appropriate Via header field" in each message it forwards. In our test, only 1 of 12 free proxies added it, so a missing Via proves nothing.
- The Server header. It should name the software of the site that answered. Through 5 of our 9 free proxies that passed the site's 500, it named the proxy's own nginx or IIS instead.
- The body. A proxy's own error page usually names the proxy. Squid's says "ERROR: The requested URL could not be retrieved" and ends with the proxy's host name and version.
Our stub test shows the difference cleanly. Relayed by the stub proxy, the site's 500 kept the site's own body and gained a Via header. When the stub proxy failed by itself, the 500 carried the proxy's name and the proxy's own body. The surest check is still to send the same request without the proxy.
What did 12 free proxies send back?
We took working HTTP proxies from our free list and asked each one for two things. One was a page that always answers 500, on httpbin.org. The other was a name ending in .invalid, which by the standard can never resolve.
| We asked for | What came back | Proxies |
|---|---|---|
| The site's 500 | 500 with the site's own Server header | 3 |
| The site's 500 | 500 with the proxy's own Server header | 5 |
| The site's 500 | 500 with no Server header | 1 |
| The site's 500 | An empty 502 in its place | 2 |
| The site's 500 | 409 from a Cloudflare host, not a real proxy | 1 |
| A host that cannot exist | 502 | 8 |
| A host that cannot exist | 503, twice with Squid's ERR_DNS_FAIL | 3 |
| A host that cannot exist | 409 | 1 |
| A host that cannot exist | 500 | 0 |

Two lessons follow. Proxies report their own trouble as 502 or 503, so a 500 points at the site. And the headers that should tell you who answered often do not, because most free proxies leave out Via or replace the Server header.
How do I fix a 500 through a proxy?
Work through these in order. The first one settles who sent it.
- Send the same request without the proxy, or through another one. If the 500 stays, the website sent it.
- For HTTPS, read the error closely. A CONNECT failure is the proxy's, whatever the site would have said.
- If the website sent it, wait. Retry later with a growing delay, and report it to the site with the time and the URL. Nothing on your side fixes a site's own failure.
- If a free proxy sent it, replace the proxy. Our free list moves every few minutes as proxies die, so a failing one is normal.
- If our gateway sent a 5xx, retry with backoff. Our docs say a persisting gateway error is ours to chase: send support the time and the line's port.
- If a chat app says "proxy error 500", look at the model's API. DeepSeek documents its 500 as its own server issue, to retry after a brief wait. OpenRouter replaces a 500's message with a generic text, which is why the app tells you so little. Our Janitor AI guide covers the other errors there.
For the code that sits next to 500 in proxy setups, see our guide to 502 Bad Gateway through a proxy. If curl is your client, our curl proxy errors guide covers the rest of its messages.
What if the 500 never goes away?
Then the website is failing for that page, and no proxy changes that. If it is your own site, start with that server's error log. If the site is behind Cloudflare and you see 520 instead, our guide to Cloudflare error 520 covers that case.
Can a better proxy help?
Not with a site's own 500. What a proxy can give you is errors that say who sent them. Our test shows free proxies turning a site's 500 into a 502 and swapping in their own Server header. Lines on our residential proxies Premium plan answer with the codes in our error reference. A failure on our side carries its own code.
What this page could not check
Twelve free proxies on one night are a small sample, and free proxies change by the hour. We did not record how many listed proxies we tried before twelve answered within 10 seconds. We did not test a paid proxy's own failures or our gateway's 5xx, because we never use a customer's line. Without credentials, our gateway answers 407, as documented. We did not test Janitor AI itself, so its wording comes from what people search. curl has already changed its message once, and providers change their error pages. We will read every source here again by 11 January 2027.
Sources
- RFC 9110, HTTP Semantics, sections 15.6.1 (500), 15.6.3 (502) and 15.6.4 (503), June 2022: rfc-editor.org.
- RFC 9110, section 9.3.6 (CONNECT), June 2022: rfc-editor.org.
- RFC 9110, sections 7.6.3 (Via) and 10.2.4 (Server), June 2022: rfc-editor.org.
- RFC 6761, Special-Use Domain Names, section 6.4 (invalid), February 2013: rfc-editor.org.
- curl source code, lib/cf-h1-proxy.c (current) and lib/http_proxy.c at tag curl-7_68_0, read 11 October 2026: github.com/curl/curl.
- curl, libcurl error codes, read 11 October 2026: curl.se.
- Squid, error templates ERR_DNS_FAIL and ERR_READ_ERROR, read 11 October 2026: github.com/squid-cache/squid.
- HProxy, API documentation, "Errors", gateway status codes, read 11 October 2026: hproxy.com/docs/errors.
- DeepSeek, API documentation, error codes, read 11 October 2026: api-docs.deepseek.com.
- OpenRouter, API documentation, errors, read 11 October 2026: openrouter.ai.
- Our own measurement: stub site and proxy, 12 free proxies and our gateway, 11 October 2026, logged in the research folder for this page.


