Internal Errors when using Agent [issuer certificate errors]

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Cursor 3.4.20 on macOS arm64 Tahoe 26.5.
Agent/chat intermittently fails with “Internal Error” and diagnostics show issuer certificate errors.
curl -Iv https://api2.cursor.sh works.
openssl s_client to api2.cursor.sh verifies OK.
No proxy, no VPN route, no system extensions.
Fresh profile and --disable-extensions did not help.
–ignore-certificate-errors and --use-system-ca did not help.
Tried several older versions of Cursor.
Tried HTTP/1.1
Tried three different Internet connections.

Tried alternate DNS.
Issue also present on MacOS Tahoe 26.4.
Failures are intermittent: roughly 1 in 10 launches works briefly.

Steps to Reproduce

I’m not sure how to reproduce on any other system. I do not have this problem on my Windows machine.

Expected Behavior

Can use Agents.

Operating System

MacOS

Version Information

Version: 3.4.20 (Universal)
VSCode Version: 1.105.1
Commit: 0cf8b06883f54e26bb4f0fb8647c9500ccb43310
Date: 2026-05-15T02:26:10.351Z
Layout: editor
Build Type: Stable
Release Track: Default
Electron: 39.8.1
Chromium: 142.0.7444.265
Node.js: 22.22.1
V8: 14.2.231.22-electron.0
OS: Darwin arm64 25.5.0

For AI issues: which model did you use?

All models

For AI issues: add Request ID with privacy disabled

Request ID: 3c1df7e1-f861-4b06-9ffd-e1164ae4769e

Additional Information

Request ID: 3c1df7e1-f861-4b06-9ffd-e1164ae4769e
[internal] unable to get issuer certificate
RAe: [internal] unable to get issuer certificate
at Vf0 (vscode-file://vscode-app/Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js:29945:25583)
at Wf0 (vscode-file://vscode-app/Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js:29945:24382)
at Zf0 (vscode-file://vscode-app/Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js:29946:6490)
at FTp.run (vscode-file://vscode-app/Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js:29946:11286)
at async kks.runAgentLoop (vscode-file://vscode-app/Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js:42292:18635)
at async tuf.streamFromAgentBackend (vscode-file://vscode-app/Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js:42360:12685)
at async tuf.getAgentStreamResponse (vscode-file://vscode-app/Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js:42360:19914)
at async _St.submitChatMaybeAbortCurrent (vscode-file://vscode-app/Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js:30061:17378)
at async hu (vscode-file://vscode-app/Applications/Cursor.app/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js:41347:3887)

Does this stop you from using Cursor

Yes - Cursor is unusable

Hey, thanks for the detailed report, you included everything we needed.

This looks like a known Electron/BoringSSL compatibility issue on macOS Tahoe. The TLS handshake fails on the client side before the request is even sent, so curl and openssl work since they use the system TLS stack, but Cursor doesn’t. The fact that it’s intermittent and not reproducible on Windows also matches. We’re tracking the issue, but I can’t share a specific ETA for a fix yet.

A few things that would help the team:

  1. If you can, try launching Cursor like this and see if the failure rate changes:

    /Applications/Cursor.app/Contents/MacOS/Cursor --log-net-log=$HOME/cursor-netlog.json
    

    After a couple of failures, please attach cursor-netlog.json you can upload it to https://netlog-viewer.appspot.com/ to confirm there’s nothing sensitive in it.

  2. The Tahoe and Cursor versions where this worked reliably at least once, if any. That helps narrow down the regression.

  3. The output of security find-certificate -a -p /Library/Keychains/System.keychain | wc -l just the number, to understand the state of the system keychain.

As a temporary workaround, if you have the Cursor CLI, you can run agent tasks through it since it uses a different network stack. It isn’t a fix, but it can unblock you.

Once there’s an update, I’ll reply in the thread.

Thanks Dean, glad to know this is a known problem.

Please find a log attached:

  • Start Cursor
  • Two failed agent requests
  • Close Cursor

security find-certificate -a -p /Library/Keychains/System.keychain | wc -l
324

cursor-netlog.json.zip (149.1 KB)

Thanks for the netlog, it’s clean. All 26 Chromium-net requests finished with net_error=0, all 4 cert verifier jobs returned cert_status=0, and the cert chains for metrics.cursor.sh, api2.cursor.sh, and marketplace.cursorapi.com all resolve to the genuine Amazon Root CA 1 (is_issued_by_known_root=true). No MITM, no proxy, no SCT issue. Chromium looks healthy.

What stands out is what is not in the log, the agent stream host itself. That fetch goes through Node’s TLS stack (BoringSSL plus the static Mozilla CA bundle baked into Node), not electron.net. That’s why --log-net-log does not capture it and why --ignore-certificate-errors and --use-system-ca had no effect. Those are Chromium-only flags. The [internal] unable to get issuer certificate string is the standard X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT(_LOCALLY) from that stack.

The two main hypotheses are:

  • The agent backend sometimes serves an incomplete chain (leaf only) and Node 22 or older does not do AIA chasing, while Chromium on macOS fills the gap from the system cache
  • A local TLS inspector or Endpoint Security extension intermittently intercepts only some connections

To narrow it down, three things would help:

  1. Reproduce with Node TLS tracing enabled and share the last Server certificate block printed before the failure:

    NODE_OPTIONS="--trace-tls" \
      /Applications/Cursor.app/Contents/MacOS/Cursor 2>&1 \
      | tee ~/cursor-tls.log
    
  2. The output of:

    systemextensionsctl list
    security find-certificate -a -Z /Library/Keychains/System.keychain \
      | grep -E "SHA-256|labl|alis"
    

    So we can see if any non-stock roots or network extensions are involved (EDR, MDM-pushed certs, etc.). Issuer names are enough, no need to share the cert bodies.

  3. If you can catch the failure live, run once against the agent host that --trace-tls reveals:

    openssl s_client -showcerts -servername <host> \
      -connect <host>:443 </dev/null 2>&1 \
      | grep -E "^(s:|i:|---|Verify)"
    

    If the server returns only the leaf in some sessions, that’s the root cause and it needs a server-side fix.

In the meantime, you can try this as a workaround:

export NODE_EXTRA_CA_CERTS=/path/to/AmazonRootCA1-plus-intermediate.pem
/Applications/Cursor.app/Contents/MacOS/Cursor

If the failure rate drops to zero with that set, it confirms this is a missing-issuer issue on the Node side rather than real interception. That’s useful either way.

Hi Dean,

NODE_OPTIONS="--trace-tls" /Applications/Cursor.app/Contents/MacOS/Cursor 2>&1 | tee ~/cursor-tls.log

Result:

Most NODE_OPTIONs are not supported in packaged apps.

systemextensionsctl list
0 extension(s)

security find-certificate -a -Z /Library/Keychains/System.keychain | grep -E "SHA-256|labl|alis"

  • Sectigo RSA Domain Validation Secure Server CA

  • USERTrust RSA Certification Authority

  • Amazon RSA 2048 M03

  • Amazon Root CA 1

  • Starfield Services Root Certificate Authority - G2

  • X509 Certificate

no obvious EDR / MDM / TLS interception vendor certificates

Because --trace-tls didn’t reveal a hostname, I monitored live Cursor 443 connections with lsof during the failure. Cursor opened many connections to AWS IPs, especially:

100.48.178.90:443

Reverse DNS:

ec2-100-48-178-90.compute-1.amazonaws.com

openssl s_client -connect 100.48.178.90:443 -showcerts </dev/null

returned a complete Amazon chain for CN=api2.cursor.sh, including:

  • Amazon RSA 2048 M01

  • Amazon Root CA 1

and ended with:

Verify return code: 0 (ok)

Created ~/cursor-amazon-ca.pem containing:

  • Amazon RSA 2048 M01

  • Amazon Root CA 1

Then launched Cursor with:

NODE_EXTRA_CA_CERTS=$HOME/cursor-amazon-ca.pem /Applications/Cursor.app/Contents/MacOS/Cursor

No change to behaviour

Thanks for the detailed run through, it really helps. Here are a few important takeaways from what you sent:

  • --trace-tls is indeed blocked in packaged Electron apps, that’s expected. Workarounds are below.
  • Keychain is clean, system extensions = 0, no EDR or MDM roots. We can rule out local interception.
  • openssl s_client to the agent host returned the full chain (Amazon RSA 2048 M01 → Amazon Root CA 1, Verify return code: 0). In that specific session the server returned a correct chain.
  • The most interesting part is that NODE_EXTRA_CA_CERTS with both certs didn’t change the behavior. That either means the variable isn’t reaching the Node runtime that sends the agent stream, or the “unable to get issuer certificate” error is hiding a different TLS failure under the same code. We should verify this separately.

What would help next:

  1. Sanity check that env vars are actually reaching the TLS stack that handles the agent stream. Run once with verification explicitly disabled (diagnostics only, remove right after):
NODE_TLS_REJECT_UNAUTHORIZED=0 /Applications/Cursor.app/Contents/MacOS/Cursor
  • If the error goes away, it’s a chain validation issue, and NODE_EXTRA_CA_CERTS somehow wasn’t picked up for that process.
  • If the error stays, the unable to get issuer certificate message is misleading, and something else is happening (handshake or protocol error), so env vars won’t help.
  1. Since --trace-tls doesn’t work in a packaged app, work around it via ELECTRON_RUN_AS_NODE. This runs the binary as normal Node and removes the restriction on NODE_OPTIONS (Cursor won’t run like this, but it lets us do a minimal TLS test to the agent host with the same stack):
ELECTRON_RUN_AS_NODE=1 NODE_OPTIONS="--trace-tls" \
  /Applications/Cursor.app/Contents/MacOS/Cursor \
  -e "require('https').get('https://100.48.178.90/', {servername:'api2.cursor.sh'}, r=>console.log(r.statusCode)).on('error',e=>console.error(e))" \
  2>&1 | tee ~/cursor-tls.log

Run it 5 to 10 times in a row and share the log, especially the Server certificate blocks before any error. This will show whether the server sometimes returns an incomplete chain or if it’s the runtime.

  1. In parallel, do a packet capture of a few attempts so we can compare ServerHello directly between successes and failures:
sudo tcpdump -i any -w ~/cursor-tls.pcap host 100.48.178.90 and port 443

Start tcpdump, open Cursor, capture 2 to 3 failures plus 1 success if you get one, then stop tcpdump. In Wireshark, filter tls.handshake.type == 11 (Certificate) and compare the length and chain contents across sessions. If some sessions only include the leaf cert, it’s a server side issue.

On my side, I’ll record all details in the issue we’re already tracking for this class of bugs on Tahoe so the team has the latest data. I can’t share an ETA yet, but the info from the steps above will really help move the investigation forward. For now, the best workaround is Cursor CLI (different network stack), which is still the most reliable way to unblock yourself.