Cursor SDK failing "[unknown] [internal] Protocol error" (~15–20s)

Where does the bug appear (feature/product)?

Cursor SDK

Describe the Bug

Summary

Headless agents started via the Python @cursor/sdk (cursor-sdk==1.0.31) consistently fail after session start:

  1. Agent.create(...) succeeds
  2. agent.send(...) returns a run that emits status=RUNNING
  3. ~15–20 seconds later: status=ERROR with message [unknown] [internal] Protocol error
  4. No assistant text, no tool calls, empty usage / empty result

Auth and model catalog work. Cursor IDE Task agents on the same account / machine / repo work fine. So this appears specific to the SDK Agent execution / streaming channel, not our prompt or pack content.


Environment

Item Value
OS macOS 26.6 (Build 25G72), Darwin 25.6.0, arm64 (Apple M-series)
Host GEIMACP4164J34CY
SDK cursor-sdk==1.0.31 (Python, latest at time of report)
Runtime Python 3.14 in project venv .venv-pilot
Auth CURSOR_API_KEY from Cursor Dashboard → Integrations (crsr_…)
Working dir Local git repo (large monorepo; also reproduces with tiny prompt)
IDE Cursor IDE Task sub-agents work on same machine/account

Expected vs actual

Related public reports (similar shape)

Our status message string is specifically [unknown] [internal] Protocol error (not stream_unavailable / ConnectError: [unavailable]), but the RUNNING→ERROR-with-empty-body pattern matches.


Asks for Cursor

  1. Look up the run IDs above on your side — did the agent stream ever attach / complete?
  2. Is this a known Agent API / transport regression for Integrations keys on 2026-09-17?
  3. For Python cursor-sdk, is there an equivalent to JS useHttp1ForAgent / forced HTTP/1.1 we should set?
  4. Any account/team entitlement required beyond models.list for Agent streaming?

Workaround in use

Continue work via Cursor IDE Task sub-agents (model=inherit / Auto→Cost). Headless SDK queue is blocked until Protocol error clears.

Steps to Reproduce

Reproduction (minimal)

import os
from pathlib import Path
from cursor_sdk import Agent, LocalAgentOptions, ModelSelection, ModelParameterValue

key = os.environ["CURSOR_API_KEY"]
model = ModelSelection(
    id="auto-smart",
    params=[ModelParameterValue(id="optimize_for", value="cost")],
)

with Agent.create(
    model=model,
    api_key=key,
    local=LocalAgentOptions(cwd=str(Path(".").resolve())),
) as agent:
    run = agent.send("Reply with exactly: OK")
    for msg in run.messages():
        if getattr(msg, "type", None) == "status":
            print(getattr(msg, "status", None), getattr(msg, "message", None))
    result = run.wait()
    print("final", result.status, result.id, repr(str(getattr(result, "result", "") or "")[:200]))

Observed:
RUNNING → ~16s → ERROR: [unknown] [internal] Protocol error → empty result.


What works vs what fails

Check Result
Cursor.models.list(api_key=...) OK — includes auto-smart with optimize_for cost / balanced / intelligence
Preflight / API key validation OK
Cursor IDE Task agents (same account, same repo) OK — used as workaround
SDK auto-smart(cost) local FAIL Protocol error
SDK auto-smart(balanced) local FAIL Protocol error
SDK composer-2.5 local FAIL Protocol error
SDK Cloud agent (CloudAgentOptions) FAIL Protocol error
VPN on vs off FAIL both ways
Prompt size / pack content Ruled out — fails on "Reply with exactly: OK"
Multi-agent role switching (extractor→critic→fix) Ruled out — fails on first agent only

Note: Python LocalAgentOptions in 1.0.31 does not expose useHttp1ForAgent / Cursor.configure({ local: ... }) (those appear in JS SDK forum guidance). We cannot apply that workaround from the Python client as documented for Node.


Production failure context (same error class)

We run a sequential headless pilot queue (Agent.create → one role → next). Failures match the smoke test:

When (UTC) Role Run ID Context
2026-09-17T23:08:19Z critic run-63f55017-efcb-41f2-8623-79137e70c7a8 #59 (VPN)
2026-09-17T23:10:09Z critic run-ef58aa8e-2007-4ce3-9585-6e863cbebcb2 #59 (retry)
2026-09-17T23:35:16Z critic run-808eb2b8-c331-416c-8ecc-b7bc15c9ba67 #59 (retry)
2026-09-17T23:41:53Z extractor run-43bde6ef-4860-480e-a747-09117acc5864 #60 after pack init
2026-09-18T00:00:01Z extractor run-236b3d42-192a-45cb-9983-75c2f2f82ad8 #61 after pack init

Example transcript lines:

[extractor] status RUNNING:
[extractor] status ERROR: [unknown] [internal] Protocol error
[extractor] === agent run end status=error result= ===

Also captured agent IDs for the latest SIU failure:
agent-fc9e6b62-44b5-49ae-914f-293dc6f6d686 / run-236b3d42-192a-45cb-9983-75c2f2f82ad8.

Smoke-test run ID from earlier triage: run-1c1c296c-aeca-496f-b911-25b5f0a122c1.


Expected Behavior

Expected: Agent stream progresses (assistant / tools / usage), then terminal success or an actionable typed error (auth, rate limit, quota, network).

Actual: Opaque [unknown] [internal] Protocol error after RUNNING; no diagnostic body; IDE path on same account still works.


Operating System

MacOS

Version Information

cursor-sdk 1.0.31

For AI issues: which model did you use?

pl. refer to above

Does this stop you from using Cursor

No - Cursor works, but with this issue

Hey @Krishna_Ponnamineni,

We checked every run and agent ID you listed - none reached our servers, and there are no errors on your account. Short version: local SDK agent runs stream over HTTP/2, while your models.list calls and the IDE use HTTP/1.1. Something on your network path (typically TLS inspection or a security proxy) is breaking the HTTP/2 stream, which surfaces as the Protocol error. It’s not your prompt, models, or account.

Fastest fix, in your control: have your network team exempt Cursor’s API domains (*.cursor.sh, especially api2.cursor.sh) from TLS/SSL inspection, or allow HTTP/2 bidirectional streaming to them. You can pinpoint it with the “Test HTTP/2 bidirectional streaming” curl here: Network Configuration | Cursor Docs

Quick answers:

  1. Streams never attached, so there’s nothing more to pull for those IDs.
  2. No Sep 17 regression - local SDK runs haven’t succeeded from this network before either.
  3. Correct - the Python SDK has no HTTP/1.1 option like the JS useHttp1ForAgent yet. We’ve let the team know.
  4. No extra entitlement needed beyond models.list.

The IDE Task agents are a solid stopgap in the meantime. We’re also looking into turning on HTTP/1.1 automatically for your org (no code change on your side) - I’ll follow up here once that’s in.

If the cloud agent (CloudAgentOptions) fails again, send the agent ID (starts with bc-) and timestamp; cloud uses a different path, so we’ll look at that one separately.

thank you for the feedback. I’ll switch to IDE task agents