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.
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)
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:
If you can, try launching Cursor like this and see if the failure rate changes:
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.
The Tahoe and Cursor versions where this worked reliably at least once, if any. That helps narrow down the regression.
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.
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:
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
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.
If you can catch the failure live, run once against the agent host that --trace-tls reveals:
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.
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:
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:
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):
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.
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):
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.
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.