Remote SSH: Extension Host crashes with TypeError: Converting circular structure to JSON (issuerCertificate)

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Cursor IDE → Remote SSH
The Remote SSH Extension Host consistently crashes a few seconds after connecting to a remote Ubuntu host.
The crash always ends with the following exception:
TypeError: Converting circular structure to JSON
property ‘issuerCertificate’ closes the circle
After this exception, the Extension Host exits and the Remote SSH session becomes unusable.
The issue is reproducible on every connection attempt.

Steps to Reproduce

  1. Launch Cursor.
  2. Connect to a remote Ubuntu machine using Remote SSH.
  3. Wait for the remote extensions and Agent services to initialize.
  4. Within a few seconds, the Extension Host crashes.

Expected Behavior

The Extension Host should initialize successfully and remain running.

Operating System

Linux

Version Information

Version: 3.13.25
VS Code Extension API: 1.128.0
Commit: 31e8d61c448c7472e371505838a0fe34083dad50
Date: 2026-07-28T06:17:45.069Z
Layout: IDE
Build Type: Stable
Release Track: Default
Electron: 40.10.3
Chromium: 144.0.7559.236
Node.js: 24.15.0
V8: 14.4.258.32-electron.0
xterm.js: 6.1.0-beta.256
OS: Darwin arm64 25.6.0

Local:
macOS 26 (Darwin arm64 25.6.0)

Remote:
Ubuntu 22.04
LXC container
Running inside OrbStack

For AI issues: which model did you use?

N/A

For AI issues: add Request ID with privacy disabled

N/A

Additional Information

Installed Remote Extensions

  • eamodio.gitlens
  • ms-python.python
  • ms-python.debugpy
  • ms-python.black-formatter
  • anysphere.cursorpyright
  • esbenp.prettier-vscode
  • redhat.vscode-yaml
  • redhat.vscode-xml
  • ms-ceintl.vscode-language-pack-ru

No unusual third-party extensions are installed.

Investigation performed:

• SSH

  • SSH connection is stable.
  • The remote server remains accessible.
  • No connection drops occur before the crash.

• AppArmor

  • The remote host does not use AppArmor.

• GitLens

  • GitLens initializes successfully.
  • No errors appear in GitLens logs.

• MCP
I inspected the logs for:

  • Context7
  • Firebase
  • Custom Odoo MCP
  • GitLens MCP

The logs do not contain any exceptions matching the JSON serialization error.

The only warning observed is:

Transient error connecting to streamableHttp server: Canceled

which appears after the Extension Host has already started shutting down.

• Extension Host

The only fatal exception found in the logs is:

TypeError: Converting circular structure to JSON
property ‘issuerCertificate’ closes the circle

The stack trace originates from the Extension Host process.

I was able to rule out:

  • unstable SSH connectivity;
  • AppArmor configuration;
  • Git repository issues.

I could not determine which component creates the object that causes the circular JSON serialization.

I have attached:

  • remoteagent.log
  • Extension Host logs
  • MCP logs

If there are any additional debug flags, logging options, or diagnostic builds that would help identify the originating component, I’d be happy to test them and provide additional logs.

Does this stop you from using Cursor

Yes - Cursor is unusable

Hey, thanks for the detailed breakdown. It’s clear you’ve already ruled out SSH, AppArmor, Git, and MCP.

The Converting circular structure to JSON … 'issuerCertificate' error almost always happens when TLS certificate verification fails on some HTTPS connection. When verification fails, Node attaches the full certificate chain to the error. That chain references itself via issuerCertificate, and trying to JSON-serialize it crashes the Extension Host. So the root cause is a failed TLS handshake, and the crash is just a side effect. A similar case was discussed here: IssuerCertificate api2.cursor.sh

Since your local Mac can reach the backend fine, and only the remote session crashes, you should look at the remote host’s egress (LXC inside OrbStack). Think proxy or antivirus traffic interception, DNS issues, or an incomplete CA store inside the container.

A few things that should help us move forward:

  • On the remote Ubuntu host, run this and share the output:

    curl -v https://api2.cursor.sh/
    

    I’m mainly interested in which certificate issuer it shows. If it’s not a real Cursor or CDN cert, but some corporate or local one, that’s the source.

  • The logs didn’t attach. There are no attachments in the post. Please re-upload them and most importantly include the full stack trace from the remote extension host log at ~/.cursor-server/data/logs/<date>/remoteexthost.log on the remote host, or from Output → Remote Extension Host. The stack will show which component is triggering the serialization.

You can also quickly try a workaround. In settings, search for HTTP/2 and enable Disable HTTP/2, then reconnect.

Once you have the curl output and the stack trace, post them here and we’ll dig in further.

Thanks for the suggestion. I tested the remote Ubuntu host (where the Extension Host runs), and I couldn’t reproduce any TLS or certificate validation issues.

Results:

  • curl -Iv https://api2.cursor.sh/
    • SSL certificate verify ok
    • HTTP/2 200
    • issuer: Google Trust Services WE1
  • openssl s_client
    • Verify return code: 0 (ok)
    • Certificate chain is valid
  • Node.js HTTPS test:
node -e "require('https').get('https://api2.cursor.sh',r=>console.log(r.statusCode)).on('error',console.error)"

returns: 200

There is no proxy configured (HTTP_PROXY, HTTPS_PROXY, SSL_CERT_FILE, NODE_EXTRA_CA_CERTS are not set), and the CA store is present and up to date.

Based on these tests, I don’t see any TLS handshake or certificate verification failures on the remote host.

Is there another Cursor endpoint besides api2.cursor.sh that could be triggering this exception? The stack trace mentions issuerCertificate, but I haven’t been able to reproduce any TLS failure outside of Cursor.

I’ve attached the complete logs again. If there’s a way to enable more verbose logging around the failing HTTPS request or the Extension Host RPC layer, I’d be happy to test it.