OmniscioGuidesConnection errors
Claude Code connection errors, from ENOTFOUND to a stalled stream
Every message Claude Code prints when a request does not reach the API, what each one is telling you about the network, and the steps Anthropic documents for it. This is the deep page for one error family. If you are looking for a different message, the error messages guide indexes the rest of them.
Checked against Anthropic's Claude Code documentation on October 23, 2026. By the Omniscio team. Updated .
One command tells you which half is broken
Before you change anything, find out whether the machine can reach the API at all. Run this in the same shell you start Claude Code from:
$ curl -I https://api.anthropic.comOn Windows PowerShell, run curl.exe -I https://api.anthropic.com so PowerShell's Invoke-WebRequest alias is not used in place of curl. Anthropic's own instructions name that detail, and it matters: the alias reports different failures and reads like a different problem.
If curl answers, the network path works and the fault is between the runtime and the network. That is the half where a leftover ANTHROPIC_BASE_URL, a proxy variable, a stale VPN interface or a container runtime is hiding. If curl fails the same way Claude Code does, fix the network path first, because nothing Claude Code can do will get past it.
The plain line, before the code
Unable to connect to API. Check your internet connectionWhat it means. This is the message underneath all of the coded ones. Anthropic's rule is that the common connection failures name the kind of failure and keep the code in parentheses, and that a code Claude Code does not recognize appears as Unable to connect to API followed by the code. So if you see this line with no code after it, or with a code you have not seen before, the section for your code may not be on this page. The diagnosis still starts in the same place: the request did not reach the API, and the curl check above tells you which half to look at.
The older form. Anthropic notes that before v2.1.227 each of these coded messages read Unable to connect to API followed by the code, with no plain-language description of what the code means:
Unable to connect to API (ECONNREFUSED)If a search result, a log or an older guide shows you that shape, read it as the same failure this page describes, and use the code to pick your section below.
Connection refused
Connection refused — a firewall or proxy may be blocking it (ConnectionRefused)What it means. Something answered the connection attempt to say no. This is not a timeout and not a DNS failure: an address resolved, a machine accepted the packet, and refused it. Anthropic notes this message can also appear as ECONNREFUSED, the same failure under its socket error name.
Why it usually happens. The commonest cause is the least obvious one: ANTHROPIC_BASE_URL is set, so Claude Code is not talking to api.anthropic.com at all. It is talking to whatever address that variable names. If that address was a local proxy or an LLM gateway that has since stopped running, you get Connection refused while curl reaches the real API without complaint, because curl never read the variable.
What to do
- Run
echo $ANTHROPIC_BASE_URL, orecho $env:ANTHROPIC_BASE_URLin PowerShell, and check theenvblock of your settings files as well. A value in a settings file survives a shell restart, so the shell check alone can come back empty. - If it names something you are not running, remove it and start Claude Code from a new terminal.
- If it names a gateway you do want, confirm the gateway is up and that its own upstream is reachable.
- If there is no
ANTHROPIC_BASE_URLat all, treat it as a firewall rule or a proxy that is refusing the connection, and see the proxy section below.
Can't reach the API server (ENOTFOUND)
Can't reach the API server — check your internet or DNS (ENOTFOUND)This is the message you searched for. What it means. The name api.anthropic.com could not be turned into an address, so there was nothing to connect to. Nothing was refused and nothing timed out, because the request never got that far. ENOTFOUND is the DNS client's own error code, and Anthropic says this message can also carry FailedToOpenSocket instead.
Why it appears. Anthropic lists three causes: no internet access at all, a VPN that blocks api.anthropic.com, and a required corporate proxy that is not configured. A VPN is the one that catches people out, because the rest of the internet keeps working while the API host does not resolve.
What to do
- Run
curl -I https://api.anthropic.comand read what it says. A DNS failure from curl confirms this is a name resolution problem rather than anything Claude Code did. - On Linux and WSL, open
/etc/resolv.confand check that the nameserver in it answers. Anthropic calls out WSL specifically: it can inherit a broken resolver from the host, so a DNS problem that does not exist on the host appears inside WSL. - On macOS, run
ifconfigand look for a staleutuninterface left behind by a VPN that was disconnected or uninstalled. Remove the VPN's network extension in System Settings, and check for routing rules it left in place. - Disconnect and reconnect the VPN, or try without it. If the API resolves without the VPN and not with it, the VPN is what is dropping it.
- Behind a corporate proxy, set
HTTPS_PROXYbefore you launch Claude Code, and add the API host to the proxy's allowlist. The hosts Claude Code needs are listed in one table.
Anthropic changed these messages in v2.1.227. Before that version, the same failure printed only Unable to connect to API (ENOTFOUND), with no plain-language description of the code. If you are reading an older log, that is the line you are looking at.
No internet route (EHOSTUNREACH)
No internet route — check your connection or VPN (EHOSTUNREACH)What it means. The name resolved, and there was still no route to send the packet down. Anthropic's own advice for this message is to check your connection or your VPN, and its three named causes for the family cover it: no internet access, a VPN that blocks api.anthropic.com, or a required corporate proxy that is not configured. Because the name did resolve, the proxy and DNS steps matter less here than the VPN and routing ones.
What to do
- Work through the ENOTFOUND steps. They are the same checks Anthropic points at for this code, and the VPN is the one to look at first.
- Check that the proxy at least allows the host, if your network requires one. The required hosts table is the list to hand your network team.
Connection dropped (ECONNRESET) and Socket is closed
Connection dropped (ECONNRESET)Socket is closedWhat they mean. Both are connections that were established and then closed before the answer finished arriving. ECONNRESET is the socket error; Socket is closed is how Claude Code describes a streaming connection that was cut while the response was still coming. Anthropic names the commonest cause directly: a corporate proxy on Windows dropping an established tunnel partway through a response.
Why it can also happen on a gateway. If ANTHROPIC_BASE_URL points at your own gateway and every request ends this way, the gateway may be rejecting the tool search fields Claude Code sends by default. Anthropic documents a check for exactly that: set ENABLE_TOOL_SEARCH=false and try again. Before v2.1.304, tool search stayed off behind a gateway unless the variable turned it on, so a gateway built against the older behaviour is the case that breaks.
What Claude Code does about it. A dropped connection before Claude has completed any part of its response is re-issued with backoff, and the turn continues even if some text had already started streaming. If the drop happens after Claude has finished thinking but before it has started any text or tool call, Claude Code re-issues the request up to two times in quick succession and then ends the turn with Connection lost before a response was produced.
What to do
- Update Claude Code with
claude update. Before v2.1.214 aSocket is closedfailure was not retried at all and the turn ended there. - If it repeats behind the same proxy, ask whoever runs it to stop closing established tunnels mid-response, and check the proxy against the required hosts.
- On a gateway of your own, try
ENABLE_TOOL_SEARCH=falseand send the same message again. - Quit any container runtime on the machine and retry. Anthropic names Docker Desktop among the things that intercept outbound traffic.
Request timed out, and No response from API
Request timed outRequest timed out. Check your internet connection and proxy settingsAPI Error: No response from API (waited 3m, then 10m on the retry). If a proxy or gateway on your network holds responses until they complete, raise API_TIMEOUT_MS or CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS to wait longer.What they mean. The API did not answer within the deadline. There are two deadlines and they are different things. The request timeout is how long an attempt has to return its response headers, and it defaults to 10 minutes. The first-byte deadline is its own, shorter deadline: on a direct Anthropic API connection it fires at 180 seconds if no response has started, and it exists so that a dead connection fails and retries instead of hanging for the full ten minutes. The third message above is what you get when the deadline passes for the retry as well, and it prints how long each attempt actually waited.
Why the two numbers differ from yours. The first-byte deadline adds one second for every 32KB of request body, so a large request legitimately waits longer. It is not the only timer running either. Anthropic documents four of them: the first-byte deadline, an event-level watchdog that aborts a stream when no response events parse, a byte-level watchdog that aborts one when no bytes arrive on the wire at all, and a body idle timeout. Each runs on a different set of connection types, which is why the page's advice is to raise a number only after you know which one is firing.
What to do
- Send the message again. A timeout on a slow network is not a setting you necessarily have to change.
- If a proxy or gateway on your network buffers responses until they are complete, raise
API_TIMEOUT_MS, orCLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MSwhere the first-byte deadline is the one firing. Both are documented in the retry behaviour table. - Keep
API_TIMEOUT_MSabove the longest wait you actually expect. A request that needs longer than the value times out again on every retry, so a value that is too low turns one slow request into a loop. - If timeouts are frequent and the network is otherwise healthy, work through the curl check and the sections above rather than raising numbers.
Streaming response ended before any complete data was received
Streaming response ended before any complete data was received. Retrying without streaming. If this keeps happening, check any proxy or gateway between Claude Code and your model provider.What it means. The streaming response completed without carrying anything Claude Code could use, so it re-sent the request without streaming to finish the turn. The warning appears once per session, in interactive sessions only. Anthropic names the usual cause plainly: a proxy or gateway that consumes or rewrites the streaming response body on its way back.
The cost of this one is easy to miss. Claude Code sends each affected request twice: once as the empty streaming attempt and once as the retry.
What to do
- Configure the proxy or gateway between Claude Code and your model provider to pass streaming response bodies and their headers through unmodified.
- On Amazon Bedrock, Anthropic documents the header and body requirements for a gateway separately, under streaming errors behind a gateway or proxy.
- If only the non-streaming route through your gateway is broken,
CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK=1turns the fallback off, except where the streaming endpoint itself returns a 404 and Claude Code still falls back.
The stalled stream next to it
A related failure is the stream that opens and then goes quiet. Claude Code aborts a stalled connection and streams the request again at most once; if it stalls a second time after Claude has finished thinking but before any text or tool call, the turn ends with The response stalled before a response was produced. While it is waiting, the spinner shows Waiting for API response · will retry in … · check your network after 20 seconds without data. That banner is not a failure yet: the countdown runs to the point where Claude Code abandons the connection. If it reappears on every attempt, treat it as a network problem and go back to the curl check.
API returned an empty or malformed response
API returned an empty or malformed response (HTTP 200) — check for a proxy or gateway intercepting the request.What it means. This is the one error on this page where the response looked successful. Claude Code re-sent a failed streaming request without streaming, got an HTTP success status, and the body was not a Claude API message: an HTML error page, a sign-in page, an empty body, or JSON in another format. Something answered in the API's place. Claude Code does not retry it, and the turn ends.
How to read it. After that opening, the message reports what actually came back. The Response: clause carries the content type, the kind of body, its size in bytes, and whether it carried an Anthropic request id. Where the response names a recognizable server, or carries intermediary headers, it names those too. That clause is the whole diagnosis: an HTML body, no Anthropic request id, or a named server in front means something between Claude Code and the API replied instead of the API.
What to do
- Read the
Response:clause and identify which system answered. - On a gateway, test the route with a direct request and fix the hop that returns the non-API response. Anthropic's gateway troubleshooting covers the hops.
- On a network with a sign-in page, such as guest Wi-Fi, complete the sign-in in a browser and then retry.
Before v2.1.271, a reply carrying a valid API message under a non-JSON content type such as text/plain also ended the turn this way, and some gateways use that content type for a non-streaming reply. Updating removes that false positive.
The proxy refused the connection
Couldn't connect through your proxy (ERR_PROXY_TUNNEL) — the proxy refused the tunnel: check its credentials and that it allows this hostartifact content fetch failed (proxy refused the connection: HTTP 407)What they mean. ERR_PROXY_TUNNEL is the proxy refusing to open the tunnel to the host Claude Code asked for. The second family appears when Claude reads artifact content, which comes from a different host: Claude Code first sends the proxy a CONNECT request, and the message carries the proxy's own answer. HTTP 407 means the proxy wanted credentials it did not get. HTTP 403 means it refuses to tunnel to that host. Any other status, such as 502, is the proxy failing to open the tunnel for its own reasons and belongs in the proxy's logs.
What to do
- Put credentials in the proxy URL itself, as
HTTPS_PROXY=http://username:password@proxy.example.com:8080. Anthropic warns against hardcoding a password in a script; use an environment variable or secure storage. - For a 403, ask whoever runs the proxy to allow the host. The required hosts table is the list to work from.
- Test the proxy from the shell you start Claude Code in:
curl -x http://proxy.example.com:8080 -I https://api.anthropic.com, with your own proxy address. If that fails the same way, fix the proxy setup first. - If the machine can reach a host directly, add it to
NO_PROXY. Keep the entry as narrow as the host you mean to bypass, because a broader entry also bypasses the proxy for other hosts that need to stay on it.
Claude Code does not support SOCKS proxies, and it never sends its WebSocket connections to localhost, ::1 or 127.0.0.0/8 through the proxy, so those do not need a NO_PROXY entry.
Where to put the proxy variables
Claude Code reads proxy variables once at startup, so a session already running will not pick up a later change to your shell. Anthropic also documents a trap that only shows up with background agents: the per-user supervisor that hosts them is one process shared by every terminal, so it inherits the environment of whichever shell happened to start it first. A proxy exported in your shell therefore reaches a background session only sometimes. Put HTTPS_PROXY, HTTP_PROXY, NO_PROXY and the CA variables in the env block of your settings file instead, which is the configuration that reaches every session.
You usually learn that a proxy address is wrong from a connection error later, because Claude Code does not validate these settings when it reads them. The one it does check at startup is the proxy URL: a value it cannot parse, such as one missing the http:// scheme, stops the launch with an error naming the variable. To confirm what loaded, start with claude --debug and read the log, or run /status and check the proxy and CA rows.
SSL certificate errors
Unable to connect to API: SSL certificate verification failed (UNABLE_TO_GET_ISSUER_CERT_LOCALLY). …Unable to connect to API: Self-signed certificate detected (SELF_SIGNED_CERT_IN_CHAIN). …What they mean. A proxy or security appliance on your network is intercepting TLS traffic with its own certificate, and Claude Code does not trust the authority that signed it. The … above stands for the rest of the message, which names the fix and links Anthropic's network configuration page. The two codes describe the same situation: UNABLE_TO_GET_ISSUER_CERT_LOCALLY means the chain does not lead to a trusted root, and SELF_SIGNED_CERT_IN_CHAIN means one of the certificates was self-signed.
The detail that matters most. A certificate validation failure is not retried. As of v2.1.199 it appears on the first attempt rather than after the full retry budget, so unlike the other errors on this page there is no wait to sit through before you act. Transient TLS conditions, such as a handshake timeout, are still retried.
What to do
- Export your organization's CA bundle and point Claude Code at it:
NODE_EXTRA_CA_CERTS=/path/to/ca-bundle.pem. - Or install the root certificate in the operating system trust store. Anthropic's network configuration page documents both roads, and it also documents
CLAUDE_CODE_CERT_STORE, which chooses between the bundled Mozilla set and the system store. - Confirm the bundle loaded. Run
claude --debugand look for the line that says the extra certificates were appended;/statusshows the path but does not check that the file loaded. - Do not set
NODE_TLS_REJECT_UNAUTHORIZEDto0. Anthropic's guidance is explicit that it disables certificate validation entirely.
The sign-in flow and the first-run connectivity check print their own version of this error, which names NODE_EXTRA_CA_CERTS and suggests running claude doctor for detail. On Amazon Bedrock, the requests Claude Code sends to AWS depend on the same certificate configuration, so a Bedrock setup behind a TLS-inspecting proxy needs the same fix on both paths.
Unable to connect to Anthropic services
Unable to connect to Anthropic services
Failed to connect to api.anthropic.com: ECONNREFUSED
Connection to api.anthropic.com timed out after 10 seconds
A proxy is configured via HTTPS_PROXY. Check that it allows connections to the host above.What it means. This is the first-run message, and the one entry here that is not about a model request. During first-run setup, before it shows the sign-in step, Claude Code checks that it can reach api.anthropic.com and platform.claude.com, gives each probe ten seconds, and exits with the reason when either check fails. It sends those probes through the same proxy configuration as API requests, and where a probe went through a proxy the message names the variable that set it.
Why it can appear when the API works. Before v2.1.222, the check used a proxy transport with no timeout at all, so a proxy configured with an https:// URL could sit on Checking connectivity... indefinitely and then fail even though ordinary API requests through that same proxy succeeded. If that is your case, claude update is the fix.
What to do
- If the message names a proxy variable, check that its value is the proxy you meant, and ask your network team to allow HTTPS connections through it to the host in the message.
- Work through the checks in the first section: the curl test and the firewall guidance apply to this check too.
- Anthropic notes one honest dead end. If your network is open and the failure still repeats, Claude Code may not be available in your country.
What Claude Code already tried before you saw this
Every message on this page arrives after Claude Code has already done something about it. It retries transient failures up to 10 times with exponential backoff, and connection failures are on that list: a dropped connection, a stalled response stream, and a streaming request that never gets response headers are each re-sent inside the retry budget. While that is happening the spinner shows a Retrying in Ns · attempt x/y countdown, and from the third attempt it names the specific reason rather than reading API error.
Two things are never retried, and both are worth knowing so you do not wait for a retry that is not coming. A TLS certificate validation failure is reported on the first attempt. And a failure that arrives after Claude has completed a block of text or a tool call is not re-run, because re-running it could execute the same tool calls twice: Claude Code keeps what Claude finished, runs the completed tool calls, and continues from their results.
The variables, and what each one is for
CLAUDE_CODE_MAX_RETRIESsets the number of attempts, 10 by default.CLAUDE_CODE_RETRY_WATCHDOG, set to1, keeps retrying capacity errors and transient failures in an unattended session such as a CI job, instead of failing after the retry count. Anthropic documents that as roughly three hours of backoff, and notes it still fails at once when a rate limit reports a spend limit or exhausted credits.API_TIMEOUT_MSis how long an attempt has to return its response headers. It does not limit how long a streaming response runs after that.CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MSsets the first-byte deadline, andCLAUDE_STREAM_IDLE_TIMEOUT_MSandCLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MSset the watchdogs' timeouts.
All four are documented, with their defaults and their limits, in Anthropic's retry behaviour table and network configuration page. Raise a number only after you know which timer is firing, because raising the wrong one does not move the deadline you are hitting.
What does not help
- Turning certificate validation off. It removes the check that told you a proxy is inspecting your traffic, and leaves the traffic still inspected. Use
NODE_EXTRA_CA_CERTS. - Reinstalling Claude Code. A connection error happens after the program is running. Anthropic keeps install and PATH failures on a separate troubleshooting page, and this is not one of them.
- Switching models. Capacity is tracked per model, so a model switch helps a 529. It does nothing for a request that never reached the API.
- Waiting for a retry on a certificate error. There is no retry. The error appears on the first attempt by design, so waiting only costs you the time.
- Trusting
curlalone as the verdict. When curl succeeds and Claude Code fails, that is a result, not a contradiction: it points atANTHROPIC_BASE_URL, a proxy variable, or something intercepting traffic on the machine. Read that gap rather than dismissing it.
One thing to expect while you work through this: the error reference changes with almost every Claude Code release, and it carries notes such as "Before v2.1.227" on individual entries. If a message you see is not on this page, it is worth reading the live reference rather than a copy of this one from a few months back.
When one session of several is the one that failed
A connection error is easy to spot when it is the only thing you are running. With several sessions going, the one that died sits in a list until you go looking for it. Omniscio is the desktop app we make for running many Claude Code sessions at once, and it treats a failure as a state rather than an interruption: a session whose process died shows as Error in red, a session that has gone quiet for a while shows as Stalled?, and both collect in the sidebar's Interrupted section instead of competing for attention with the sessions that are waiting on a decision from you. The session statuses page documents all eleven states, the orchestration page covers running the group, and the features page lists what else is in the app today. Installers are on the download page.
If you are working through the steps on this page, the guide to running several sessions is where the habits around that are written down.
Sources
Every message quoted on this page and every step under it comes from one of these, each read in its Markdown form on October 23, 2026.
- Claude Code error reference, for the network and connection messages and their recovery steps, the automatic retry rules, the server-error timing entries, and the retry variables.
- Enterprise network configuration, for the proxy variables, basic authentication, the certificate store and custom CA setup, the streaming idle watchdogs, the required hosts table, and the rules for background agents.
- Install and update troubleshooting, named here only to say which failures belong to it rather than to this page.
Anthropic documents each of these messages in one place, under a heading of its own, with the "What to do" steps underneath it. This page reorganises that material by the question a reader actually has, and it puts Anthropic's own curl check first, because the reference's note that a failure with curl succeeding points at something between the runtime and the network is the fastest thing to establish before you work down a list.
Common questions
What does ENOTFOUND mean in Claude Code?
It means the name api.anthropic.com could not be resolved to an address, so the request never left your machine to reach the API. Anthropic prints it as: Can't reach the API server — check your internet or DNS (ENOTFOUND). Start with DNS: check /etc/resolv.conf on Linux and WSL, and check for a stale VPN tunnel on macOS.
Why does Claude Code say connection refused when curl works?
Almost always a leftover ANTHROPIC_BASE_URL. When that variable is set, Claude Code sends model requests to that address instead of api.anthropic.com, so a value pointing at a proxy or gateway that has stopped running gives Connection refused while curl still reaches the real API. Run echo $ANTHROPIC_BASE_URL, and check the env block of your settings files.
Is a Claude Code connection error ever Anthropic's fault?
Sometimes. A 500 or a 529 comes from Anthropic's side, and those are the two entries where the fix is to check status.claude.com and try again. The errors on this page are the other kind: the request never reached the API, or a proxy on your network changed or dropped what came back.
Does Claude Code retry a connection error on its own?
Yes. Claude Code retries transient failures up to 10 times with exponential backoff, and dropped connections and stalled streams are on that list. A TLS certificate validation failure is not retried, so it appears on the first attempt. When you see any of these messages, the retries that apply to it have already happened.
What is the difference between a stalled stream and a dropped connection?
A dropped connection is closed, and Claude Code re-issues the request. A stalled stream is still open but has stopped delivering: a watchdog aborts it when no bytes arrive, and Claude Code streams the request again at most once. If either one happens after Claude has finished a block of text or a tool call, Claude Code does not re-run the request: it keeps what was completed and continues the turn from there.
Should I set NODE_TLS_REJECT_UNAUTHORIZED=0 to get past a certificate error?
No. Anthropic says not to set it, because it turns certificate validation off entirely. Export your organization's CA bundle and point Claude Code at it with NODE_EXTRA_CA_CERTS instead.
Which hosts does Claude Code need to reach?
api.anthropic.com carries the model requests. claude.ai and platform.claude.com carry sign-in, and platform.claude.com also carries the OAuth token exchange, refresh and revocation, so both sign-in methods need it. Anthropic's network configuration page lists the full set, including the optional hosts you can drop by turning a feature off.