Cursor “Connection Failed” and HTTP/2 Errors: Every Fix That Actually Works
“Connection failed. If the problem persists, please check your internet connection or VPN” is one of the most reported Cursor errors, and it is frustrating because it often appears on connections that work everywhere else. The message is generic, so no single fix cures every case. What exists is an ordered set of fixes, each with a different level of evidence: some are in Cursor's documentation, some come from Cursor staff replies on the forum, and some are single-user reports. This guide ranks them honestly and says which is which.
The 60-second version. Open Cursor Settings, Network, run Run Diagnostics, then set HTTP Compatibility Mode to HTTP/1.1 and restart Cursor. Cursor's documentation says it streams over HTTP/2 and some corporate proxies block that, and forum staff say switching fixes most cases. If it does not, work down the checklist below. Evidence levels are labeled because forum advice is not a guarantee, and exact setting names change between versions.
What the error actually means
The message says Cursor could not complete a request to its servers. It does not say why. Reports on the Cursor forum tie it to several different things: HTTP/2 not working well on some networks, too many connected MCP tools, firewall or antivirus interference, VPN or proxy behavior, and in a few cases a stuck chat or corrupted local state. In one thread, users on Linux, macOS, and Windows saw it together with SSLV3_ALERT_HANDSHAKE_FAILURE in the logs, and some said TLS worked from openssl and curl --http2 on the same machine. That points at the path between Cursor's own network stack and its servers, not at the internet being down.
Why HTTP/2 comes up so often
Cursor's documentation states that it uses HTTP/2 for streaming responses and that some corporate proxies, such as Zscaler, block it. HTTP/2 multiplexes many streams over one long-lived connection, so a proxy, VPN, or security tool that mishandles that connection can break streaming while ordinary web browsing still seems fine. Forum staff describe the error as a known issue on some networks with HTTP/2 and recommend the HTTP/1.1 switch first. Two honest caveats: staff have not published a confirmed root cause, and some users report HTTP/2 stopping and starting to work on the same version with no changes, so a version bug is not the whole story either. The same family of problem is covered generally in our guide to debugging streaming failures.
The fix checklist, in order, with evidence
| # | Step | Evidence | Why |
|---|---|---|---|
| 1 | Run Cursor Settings, Network, Run Diagnostics | Documented | Tests your connection to Cursor's servers and flags problems affecting AI features or updates |
| 2 | Set HTTP Compatibility Mode to HTTP/1.1 (forum wording: enable Disable HTTP/2), then restart | Documented for proxy cases; staff-recommended and user-reported for general cases | Cursor streams over HTTP/2 and some proxies, such as Zscaler, block it. Staff say it fixes most cases; users say it is the workaround that helped most consistently |
| 3 | Test without VPN, proxy, or SSL inspection, or on another network | Staff forum reply | Separates a network-path problem from a Cursor problem |
| 4 | Disable unused MCP servers | Staff forum reply; one user report | Staff list MCP tool count as a common cause and cite an 80-tool limit |
| 5 | Launch with cursor --disable-extensions and test in a new chat | Staff forum reply | Rules out an extension |
| 6 | Check firewall and antivirus; allow Cursor's domains | Documented (domains); staff forum reply (antivirus) | Allowlist *.cursor.sh, *.cursor-cdn.com, *.cursorapi.com, cursor.com, and *.cursor.com; sign-in needs additional hosts |
| 7 | Fully restart Cursor after leaving a VPN | Documented | Cursor can inherit DNS settings from a previously active VPN |
| 8 | Start a new chat; as a last resort clear workspace state | User-reported, unconfirmed | One user saw the failure start with a second agent chat and clear when chat state was removed. This deletes chat history |
| 9 | Collect and send diagnostics | Staff request | Request ID (Copy Request Details), Run Diagnostics output, version from Help, About, and console errors from Help, Toggle Developer Tools |
Do the steps one at a time and test in a new chat after each, so you learn which change mattered. If step 2 fixes it, stop; there is no benefit to changing more.
Fixes by situation
| Your situation | Likely cause | Fix |
|---|---|---|
| Behind a corporate proxy (for example Zscaler) | HTTP/2 blocked for streaming | HTTP/1.1 mode; ask IT to allow Cursor's domains |
| Cloud agents stay on Loading on cursor.com but work in the desktop app | A secure web gateway (Cloudflare WARP, Zscaler, Netskope) may be scanning responses and holding the stream open | Test with the gateway off or on another network; ask IT to exclude cursor.com and *.cursor.com from TLS inspection and file scanning |
| Over SSH or a remote connection | AI requests go from your local machine; dropped sessions leave stale processes | Check local connection and remote resources; ServerAliveInterval 60, ServerAliveCountMax 3; restart Cursor |
| After disconnecting a VPN | Inherited VPN DNS settings | Full restart; verify system DNS (scutil --dns on macOS, /etc/resolv.conf on Linux) |
| Suspicious activity message | Blocked as a security measure; a VPN can trigger it | Turn off the VPN; new chat; wait a few minutes; or sign in with Google or GitHub |
If you are on a company network
Ask IT to allow Cursor's domains, and tell them whether TLS inspection is in use. The documented allowlist is *.cursor.sh (including authenticate.cursor.sh and authenticator.cursor.sh), *.cursor-cdn.com, *.cursorapi.com (including marketplace.cursorapi.com), cursor.com and *.cursor.com. Sign-in needs additional hosts listed in Cursor's sign-in domains article, so check the current network documentation, because required hosts change. HTTP/1.1 mode is the quickest workaround while IT sorts out the proxy.
A triage script that gives you the order
The script below turns what you observe into an ordered list of steps, each labeled with its evidence level, so you do not skip the documented ones or present a user report as a guarantee. It also has a helper that returns which of Cursor's hosts you cannot reach, given any probe function you supply. The tests run without Cursor installed.
from dataclasses import dataclass, field
DOCUMENTED, STAFF, USER = "documented", "staff-forum", "user-reported"
CURSOR_HOSTS = ["cursor.com", "authenticate.cursor.sh", "marketplace.cursorapi.com"]
@dataclass
class Observation:
error_text: str = ""
http_mode: str = "default" # "default" or "http1"
behind_proxy_or_vpn: bool = False
after_vpn_disconnect: bool = False
over_ssh: bool = False
mcp_tool_count: int = 0
diagnostics_passed: bool = None # None = not run yet
fails_only_in_one_chat: bool = False
failed_hosts: list = field(default_factory=list)
@dataclass
class Step:
action: str
evidence: str
why: str
def triage(o: Observation, mcp_limit: int = 80) -> list:
steps = []
if o.diagnostics_passed is None:
steps.append(Step("Cursor Settings > Network > Run Diagnostics", DOCUMENTED,
"Tests the connection to Cursor's servers and flags what breaks AI features."))
if o.http_mode != "http1":
why = ("HTTP/2 is used for streaming and some proxies block it."
if o.behind_proxy_or_vpn else "Staff and users report HTTP/2 problems on some networks.")
steps.append(Step("Set HTTP Compatibility Mode to HTTP/1.1, then restart Cursor",
DOCUMENTED if o.behind_proxy_or_vpn else STAFF, why))
if o.after_vpn_disconnect:
steps.append(Step("Fully restart Cursor and confirm system DNS reverted", DOCUMENTED,
"Cursor can inherit DNS settings from a previously active VPN."))
if o.failed_hosts:
steps.append(Step("Allow these hosts in your firewall: " + ", ".join(sorted(o.failed_hosts)),
DOCUMENTED, "Firewalls blocking outbound connections to Cursor's domains break AI features."))
if o.behind_proxy_or_vpn:
steps.append(Step("Test without the VPN, proxy, or SSL inspection, or on another network",
STAFF, "Isolates whether the network path is the cause."))
if o.over_ssh:
steps.append(Step("Check local connectivity and remote CPU and memory; add ServerAliveInterval 60 and ServerAliveCountMax 3",
DOCUMENTED, "AI requests leave from your local machine; dropped SSH sessions leave stale processes."))
if o.mcp_tool_count > mcp_limit * 0.75:
steps.append(Step(f"Disable unused MCP servers ({o.mcp_tool_count} tools connected)", STAFF,
f"A staff reply cites a tool limit of {mcp_limit}; one user fixed the error this way."))
if o.fails_only_in_one_chat:
steps.append(Step("Start a new chat; if the problem follows the workspace, back up and clear its chat state as a last resort",
USER, "One user traced it to a second agent chat; unconfirmed."))
if o.diagnostics_passed is False or o.http_mode == "http1":
steps.append(Step("Collect Request ID, diagnostics output, version, and console errors for support",
STAFF, "These are what staff ask for when the usual fixes fail."))
if "SSLV3_ALERT_HANDSHAKE_FAILURE" in o.error_text:
steps.append(Step("Note the TLS handshake error in your report", USER,
"Reported alongside Connection failed on several operating systems; no root cause confirmed."))
return steps
def unreachable(probe, hosts=CURSOR_HOSTS) -> list:
"""probe(host) -> bool. Returns the hosts that could not be reached."""
return [h for h in hosts if not probe(h)]
def acts(steps):
return [s.action for s in steps]
def test_default_flow_runs_diagnostics_then_http1():
s = triage(Observation(error_text="Connection failed"))
assert acts(s)[0].startswith("Cursor Settings > Network > Run Diagnostics")
assert any("HTTP/1.1" in a for a in acts(s))
def test_proxy_makes_http1_advice_documented_not_forum_only():
s = triage(Observation(behind_proxy_or_vpn=True, diagnostics_passed=False))
h = [x for x in s if "HTTP/1.1" in x.action][0]
assert h.evidence == DOCUMENTED
plain = [x for x in triage(Observation(diagnostics_passed=False)) if "HTTP/1.1" in x.action][0]
assert plain.evidence == STAFF
def test_http1_already_set_is_not_repeated_and_escalates():
s = triage(Observation(http_mode="http1", diagnostics_passed=False))
assert not any("HTTP/1.1" in a for a in acts(s))
assert any("Request ID" in a for a in acts(s))
def test_vpn_disconnect_and_ssh_steps():
s = acts(triage(Observation(after_vpn_disconnect=True, over_ssh=True, diagnostics_passed=True)))
assert any("DNS" in a for a in s)
assert any("ServerAliveInterval" in a for a in s)
def test_mcp_advice_only_when_near_the_limit():
assert not any("MCP" in a for a in acts(triage(Observation(mcp_tool_count=10))))
s = triage(Observation(mcp_tool_count=70))
m = [x for x in s if "MCP" in x.action][0]
assert m.evidence == STAFF and "70 tools" in m.action
def test_failed_hosts_are_listed_sorted_and_single_chat_is_user_reported():
s = triage(Observation(failed_hosts=["b.cursor.sh", "a.cursor.sh"], fails_only_in_one_chat=True))
host = [x for x in s if x.action.startswith("Allow")][0]
assert host.action.endswith("a.cursor.sh, b.cursor.sh")
chat = [x for x in s if "new chat" in x.action][0]
assert chat.evidence == USER
def test_unreachable_uses_probe():
assert unreachable(lambda h: h != "cursor.com") == ["cursor.com"]
assert unreachable(lambda h: True) == []
What not to do
- Do not reinstall first. One user reported reinstalling as the only fix that worked, but that was a single report and cheaper steps come first.
- Do not delete state before backing up. It removes chat history, and the evidence for it is one user's observation.
- Do not paste Request IDs, console logs, or screenshots publicly without checking them. They can contain workspace paths and account details.
- Do not assume the usage limit is the problem. A staff reply to a user with this error said it is not related to the limit.
If nothing works
Send the information staff ask for: two or three recent Request IDs from Copy Request Details, the Run Diagnostics output, your Cursor version from Help, About, and console errors from Help, Toggle Developer Tools, plus whether a VPN, proxy, or SSL inspection is in the path. For how this error compares with failures in other coding assistants, see Cursor vs Claude Code vs Copilot, and for the same class of problem in Claude Code see Top Claude Code Errors in 2026. If your own code calls model APIs, the broader API error troubleshooting directory covers it.
Sources
- Cursor documentation: Common issues
- Cursor Help: Network troubleshooting
- Cursor forum: Frequent “Connection Failed” errors despite stable internet connection (not official documentation)
- Cursor forum: HTTP/2 makes Cursor unusable (not official documentation)
- Cursor forum: Repeatedly says connection issue when my connection is fine (not official documentation)
- Cursor forum: Always show “connection Error” but usage not to the limit (not official documentation)
Frequently asked questions
Why does Cursor say “Connection failed. If the problem persists, please check your internet connection or VPN”?
It is a generic message with several possible causes. Cursor staff replies on the forum describe it as a known issue on some networks with HTTP/2, and also mention too many MCP tools and firewall or antivirus interference. Cursor's documentation says Cursor uses HTTP/2 for streaming and that some corporate proxies, such as Zscaler, block it. Work through the checklist above in order.
How do I disable HTTP/2 in Cursor?
Open Cursor Settings, go to Network, and set HTTP Compatibility Mode to HTTP/1.1, then restart Cursor. Forum replies describe the same thing as searching Settings for HTTP/2 and enabling Disable HTTP/2. The exact label can differ between versions, so search the settings for HTTP.
Does disabling HTTP/2 always fix Connection failed?
No. A Cursor staff reply says it fixes most cases in their experience, and forum users report it as the workaround that helped most consistently, but none of that is a guarantee. Some users report the error returning, and a few found a different cause such as MCP servers, a stuck chat, or corrupted local state.
What does SSLV3_ALERT_HANDSHAKE_FAILURE mean in the Cursor logs?
It is a TLS handshake failure. In one forum thread, users on several operating systems saw it together with the Connection failed message, and some reported that TLS worked from other tools such as curl while Cursor's own diagnostics failed. Staff acknowledged it as a known issue on some networks with HTTP/2 without confirming a root cause. Switching to HTTP/1.1 was the workaround users reported.
Can too many MCP servers cause Connection failed?
Possibly. A staff reply on the forum lists the MCP tool count as one common cause, and one user reported that disabling their MCP servers except browser automation stopped the error. Staff also said Cursor has an 80-tool limit. That figure comes from a forum reply rather than documentation, so verify it for your version.
Should I delete Cursor's local state?
Only as a last resort. One forum user reported that the problem began with a second agent chat and cleared when workspace chat state was removed, but this was an observation, not a confirmed cause, and deleting state removes chat history. Try the network and settings steps first.
Why does Cursor fail after I disconnect from a VPN?
Cursor's documentation says it can inherit DNS settings from a previously active VPN. Fully restart Cursor rather than just reloading the window, and check that your system DNS has reverted to normal.
What should I send to Cursor support or the forum?
Staff asked for the Request ID (via Copy Request Details), the output of Run Diagnostics, the version from Help, About, and console errors from Help, Toggle Developer Tools. Remove anything sensitive before posting.
Does Connection failed mean my internet is down?
Not necessarily. Several forum users reported the error on connections that tested fine elsewhere. The message points at the path between Cursor and its servers, which includes proxies, VPNs, security software, and the HTTP version in use.