Cursor IDE overwrites ARCH env variable in an env container

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

I asked Cursor to summarize the issue based on our troubleshooting session:
Cursor’s remote server bootstrap pollutes the environment of every integrated terminal and every Agent shell tool with ARCH= (e.g. ARCH=x86_64). VSCode Remote‑SSH on the same machine, against the same container, does not exhibit this — the env is clean.

The leak comes from ~/.cursor-server/bin//bin/helpers/check-requirements.sh, which contains:

ARCH=$(uname -m)
(no local, no subshell). When the bootstrap sources this script instead of executing it as a subprocess, the assignment leaks into the parent shell, then into the cursor-server process, and from there into every shell it spawns. VSCode ships the same upstream Microsoft script but apparently runs it as a subprocess, so the leak never happens.

This breaks projects that use ARCH as a meaningful build/cross‑compile selector. In my case (Yocto SDK / cargo cross‑compile project), ARCH is supposed to be one of qemux86-64 | sm6-snowfish-nrt | sm7-marlin, and the project’s profile.d script gracefully defaults it when unset. The leaked ARCH=x86_64 triggers a WARNING: Unknown ARCH=x86_64. You can experience problems with rust. and silently skips CARGO_BUILD_TARGET / CARGO_TARGET_*_LINKER setup.

Steps to Reproduce

Set up any container/remote where the launching env intentionally sets ARCH to something other than the host arch (e.g. docker run --env ARCH=qemux86-64 …).
Connect with Cursor.
In a Cursor integrated terminal (or Agent shell), run echo $ARCH — it prints the host’s uname -m, not the value the container was started with.
Repeat with VSCode Remote‑SSH against the same container — it prints the value the container was started with.
Verifiable from /proc:

tr ‘\0’ ‘\n’ < /proc/1/environ | grep ^ARCH= → ARCH=qemux86-64 (correct)
tr ‘\0’ ‘\n’ < /proc//environ | grep ^ARCH= → ARCH=x86_64 (leaked)

Expected Behavior

The remote bootstrap should not modify ARCH (or any other unrelated env var) in the cursor-server process. The user’s terminal/agent shells should see exactly the env that container PID 1 was started with.

Suggested one‑liner fixes on Cursor’s side, in priority order:

Run check-requirements.sh as a subprocess instead of sourcing it (matches VSCode behavior).
Or, in check-requirements.sh, wrap the body in a subshell ( … ) or replace ARCH=$(uname -m) with a non‑leaking pattern (e.g. _arch=$(uname -m), then use $_arch).
Or, unset ARCH at the end of the script.

Operating System

Linux

Version Information

Version: 3.3.27
VSCode Version: 1.105.1
Commit: 80b138a7a0a948e1a798e9ed7867d76a1ba9a310
Date: 2026-05-08T02:26:22.498Z
Layout: editor
Build Type: Stable
Release Track: Default
Electron: 41.5.0
Chromium: 146.0.7680.216
Node.js: 24.15.0
V8: 14.6.202.34-electron.0
OS: Linux x64 7.0.3-arch1-2

For AI issues: which model did you use?

Opus 4.7

Additional Information

It would also be nice if the remote bootstrap honored ~/.cursor-server/server-env-setup the way VSCode honors ~/.vscode-server/server-env-setup. That’s the documented escape hatch users reach for first when they hit env leaks like this, and currently it appears to be a no‑op in Cursor — created the file with unset ARCH, restarted the cursor-server, and confirmed the bootstrap process still has ARCH=x86_64 directly in its /proc/…/environ.

Both the VSCode code-server and the Cursor cursor-server launcher scripts are identical (“$ROOT/node” ${INSPECT:-} “$ROOT/out/server-main.js” “$@”), so the divergence is entirely in the layer above — i.e., how the bootstrap invokes check-requirements.sh and whether it reads server-env-setup.

Does this stop you from using Cursor

Sometimes - I can sometimes use Cursor

Thanks for the detailed report and the /proc evidence.

To help us narrow down what’s different about your setup, could you share a couple more details?

  1. The cursor-server bootstrap script on your remote — run:

    cat ~/.cursor-server/bin/*/bin/cursor-server
    
  2. The process tree showing how cursor-server was launched:

    pstree -p $(pgrep -f "server-main.js" | head -1) -s

  3. Is this a Docker container you’re connecting to, or a bare Linux host/VM? If Docker, are you using docker exec-style connections or SSH into the container?

  4. The full contents of ~/.cursor-server/bin/*/bin/helpers/check-requirements.sh on your remote

This will help us identify which layer is sourcing the script on your system.

Thanks for the reply.

$ cat ~/.cursor-server/bin/*/bin/cursor-server
#!/usr/bin/env sh
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#

case "$1" in
	--inspect*) INSPECT="$1"; shift;;
esac

ROOT="$(dirname "$(dirname "$(readlink -f "$0")")")"

# Set rpath before changing the interpreter path
# Refs https://github.com/NixOS/patchelf/issues/524
if [ -n "$VSCODE_SERVER_CUSTOM_GLIBC_LINKER" ] && [ -n "$VSCODE_SERVER_CUSTOM_GLIBC_PATH" ] && [ -n "$VSCODE_SERVER_PATCHELF_PATH" ]; then
	echo "Patching glibc from $VSCODE_SERVER_CUSTOM_GLIBC_PATH with $VSCODE_SERVER_PATCHELF_PATH..."
	"$VSCODE_SERVER_PATCHELF_PATH" --set-rpath "$VSCODE_SERVER_CUSTOM_GLIBC_PATH" "$ROOT/node"
	echo "Patching linker from $VSCODE_SERVER_CUSTOM_GLIBC_LINKER with $VSCODE_SERVER_PATCHELF_PATH..."
	"$VSCODE_SERVER_PATCHELF_PATH" --set-interpreter "$VSCODE_SERVER_CUSTOM_GLIBC_LINKER" "$ROOT/node"
	echo "Patching complete."
fi

"$ROOT/node" ${INSPECT:-} "$ROOT/out/server-main.js" "$@"


2.
$ pstree -p $(pgrep -f "server-main.js" | head -1) -s
systemd(1)───conmon(300590)───sh(300593)───node(300597)─┬─node(300794)─┬─bash(992612)
                                                        │              ├─{node}(300795)
                                                        │              ├─{node}(300796)
                                                        │              ├─{node}(300797)
                                                        │              ├─{node}(300798)
                                                        │              ├─{node}(300799)
                                                        │              ├─{node}(300800)
                                                        │              ├─{node}(300801)
                                                        │              ├─{node}(300802)
                                                        │              ├─{node}(300803)
                                                        │              ├─{node}(300804)
                                                        │              └─{node}(992613)
                                                        ├─node(2343824)─┬─{node}(2343825)
                                                        │               ├─{node}(2343826)
                                                        │               ├─{node}(2343827)
                                                        │               ├─{node}(2343828)
                                                        │               ├─{node}(2343829)
                                                        │               ├─{node}(2343830)
                                                        │               ├─{node}(2343831)
                                                        │               ├─{node}(2343832)
                                                        │               ├─{node}(2343833)
                                                        │               ├─{node}(2343834)
                                                        │               ├─{node}(2343835)
                                                        │               └─{node}(2343836)
                                                        ├─node(2343840)─┬─rust-analyzer(2344130)─┬─rust-analyzer-p(2344267)
                                                        │               │                        ├─{rust-analyzer}(2344131)
                                                        │               │                        ├─{rust-analyzer}(2344132)
                                                        │               │                        ├─{rust-analyzer}(2344133)
                                                        │               │                        ├─{rust-analyzer}(2344134)
                                                        │               │                        ├─{rust-analyzer}(2344135)
                                                        │               │                        ├─{rust-analyzer}(2344136)
                                                        │               │                        ├─{rust-analyzer}(2344137)
                                                        │               │                        ├─{rust-analyzer}(2344138)
                                                        │               │                        ├─{rust-analyzer}(2344139)
                                                        │               │                        ├─{rust-analyzer}(2344140)
                                                        │               │                        ├─{rust-analyzer}(2344141)
                                                        │               │                        ├─{rust-analyzer}(2344142)
                                                        │               │                        ├─{rust-analyzer}(2344143)
                                                        │               │                        ├─{rust-analyzer}(2344144)
                                                        │               │                        ├─{rust-analyzer}(2344145)
                                                        │               │                        ├─{rust-analyzer}(2344146)
                                                        │               │                        ├─{rust-analyzer}(2344147)
                                                        │               │                        ├─{rust-analyzer}(2344148)
                                                        │               │                        ├─{rust-analyzer}(2344149)
                                                        │               │                        ├─{rust-analyzer}(2344150)
                                                        │               │                        ├─{rust-analyzer}(2344151)
                                                        │               │                        ├─{rust-analyzer}(2344152)
                                                        │               │                        ├─{rust-analyzer}(2344153)
                                                        │               │                        ├─{rust-analyzer}(2344154)
                                                        │               │                        ├─{rust-analyzer}(2344155)
                                                        │               │                        ├─{rust-analyzer}(2344156)
                                                        │               │                        ├─{rust-analyzer}(2344157)
                                                        │               │                        ├─{rust-analyzer}(2344158)
                                                        │               │                        ├─{rust-analyzer}(2344159)
                                                        │               │                        ├─{rust-analyzer}(2344160)
                                                        │               │                        ├─{rust-analyzer}(2344161)
                                                        │               │                        ├─{rust-analyzer}(2344162)
                                                        │               │                        ├─{rust-analyzer}(2344163)
                                                        │               │                        ├─{rust-analyzer}(2344164)
                                                        │               │                        ├─{rust-analyzer}(2344165)
                                                        │               │                        ├─{rust-analyzer}(2344166)
                                                        │               │                        ├─{rust-analyzer}(2344167)
                                                        │               │                        ├─{rust-analyzer}(2344168)
                                                        │               │                        ├─{rust-analyzer}(2344169)
                                                        │               │                        ├─{rust-analyzer}(2344170)
                                                        │               │                        ├─{rust-analyzer}(2344171)
                                                        │               │                        ├─{rust-analyzer}(2344172)
                                                        │               │                        ├─{rust-analyzer}(2344173)
                                                        │               │                        ├─{rust-analyzer}(2344174)
                                                        │               │                        ├─{rust-analyzer}(2344175)
                                                        │               │                        ├─{rust-analyzer}(2344176)
                                                        │               │                        ├─{rust-analyzer}(2344177)
                                                        │               │                        ├─{rust-analyzer}(2344178)
                                                        │               │                        ├─{rust-analyzer}(2344179)
                                                        │               │                        ├─{rust-analyzer}(2344180)
                                                        │               │                        ├─{rust-analyzer}(2344181)
                                                        │               │                        ├─{rust-analyzer}(2344182)
                                                        │               │                        ├─{rust-analyzer}(2344183)
                                                        │               │                        ├─{rust-analyzer}(2344184)
                                                        │               │                        ├─{rust-analyzer}(2344185)
                                                        │               │                        ├─{rust-analyzer}(2344186)
                                                        │               │                        ├─{rust-analyzer}(2344187)
                                                        │               │                        ├─{rust-analyzer}(2344188)
                                                        │               │                        ├─{rust-analyzer}(2344189)
                                                        │               │                        ├─{rust-analyzer}(2344190)
                                                        │               │                        ├─{rust-analyzer}(2344191)
                                                        │               │                        ├─{rust-analyzer}(2344192)
                                                        │               │                        ├─{rust-analyzer}(2344193)
                                                        │               │                        ├─{rust-analyzer}(2344194)
                                                        │               │                        ├─{rust-analyzer}(2344195)
                                                        │               │                        ├─{rust-analyzer}(2344196)
                                                        │               │                        ├─{rust-analyzer}(2344197)
                                                        │               │                        ├─{rust-analyzer}(2344198)
                                                        │               │                        ├─{rust-analyzer}(2344199)
                                                        │               │                        ├─{rust-analyzer}(2344200)
                                                        │               │                        ├─{rust-analyzer}(2344201)
                                                        │               │                        ├─{rust-analyzer}(2344348)
                                                        │               │                        ├─{rust-analyzer}(2344527)
                                                        │               │                        ├─{rust-analyzer}(2344694)
                                                        │               │                        └─{rust-analyzer}(2347076)
                                                        │               ├─{node}(2343841)
                                                        │               ├─{node}(2343842)
                                                        │               ├─{node}(2343843)
                                                        │               ├─{node}(2343844)
                                                        │               ├─{node}(2343845)
                                                        │               ├─{node}(2343846)
                                                        │               ├─{node}(2343847)
                                                        │               ├─{node}(2343848)
                                                        │               ├─{node}(2343849)
                                                        │               ├─{node}(2343850)
                                                        │               └─{node}(2343870)
                                                        ├─{node}(300598)
                                                        ├─{node}(300599)
                                                        ├─{node}(300600)
                                                        ├─{node}(300601)
                                                        ├─{node}(300602)
                                                        ├─{node}(300603)
                                                        ├─{node}(300605)
                                                        ├─{node}(300606)
                                                        ├─{node}(300607)
                                                        └─{node}(300608)
  1. This is a remote container ran by podman. The container is started manually by me on the remote host. Then I’m using the Dev Containers functionality in Cursor. SSH connection is done to the remote host, I’m not sure how Cursor attaches to the running container.
$ cat ~/.cursor-server/bin/*/bin/helpers/check-requirements.sh
#!/usr/bin/env sh
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#

set -e

# The script checks necessary server requirements for the classic server
# scenarios. Currently, the script can exit with any of the following
# 2 exit codes and should be handled accordingly on the extension side.
#
# 0: All requirements are met, use the default server.
# 99: Unsupported OS, abort server startup with appropriate error message.
#

# Do not remove this check.
# Provides a way to skip the server requirements check from
# outside the install flow. A system process can create this
# file before the server is downloaded and installed.
if [ -f "/tmp/vscode-skip-server-requirements-check" ] || [ -n "$VSCODE_SERVER_CUSTOM_GLIBC_LINKER" ]; then
    echo "!!! WARNING: Skipping server pre-requisite check !!!"
    echo "!!! Server stability is not guaranteed. Proceed at your own risk. !!!"
    exit 0
fi

ARCH=$(uname -m)
found_required_glibc=0
found_required_glibcxx=0
MIN_GLIBCXX_VERSION="3.4.25"

# Extract the ID value from /etc/os-release
if [ -f /etc/os-release ]; then
    OS_ID="$(cat /etc/os-release | grep -Eo 'ID=([^"]+)' | sed -n '1s/ID=//p')"
    if [ "$OS_ID" = "nixos" ]; then
        echo "Warning: NixOS detected, skipping GLIBC check"
        exit 0
    fi
fi

# Based on https://github.com/bminor/glibc/blob/520b1df08de68a3de328b65a25b86300a7ddf512/elf/cache.c#L162-L245
case $ARCH in
	x86_64) LDCONFIG_ARCH="x86-64";;
	armv7l | armv8l)
        MIN_GLIBCXX_VERSION="3.4.26"
        LDCONFIG_ARCH="hard-float"
        ;;
	arm64 | aarch64)
        BITNESS=$(getconf LONG_BIT)
		if [ "$BITNESS" = "32" ]; then
			# Can have 32-bit userland on 64-bit kernel
			LDCONFIG_ARCH="hard-float"
		else
			LDCONFIG_ARCH="AArch64"
		fi
		;;
esac

if [ "$OS_ID" != "alpine" ]; then
    if [ -f /sbin/ldconfig ]; then
        # Look up path
        libstdcpp_paths=$(/sbin/ldconfig -p | grep 'libstdc++.so.6')

        if [ "$(echo "$libstdcpp_paths" | wc -l)" -gt 1 ]; then
            libstdcpp_path=$(echo "$libstdcpp_paths" | grep "$LDCONFIG_ARCH" | awk '{print $NF}')
        else
            libstdcpp_path=$(echo "$libstdcpp_paths" | awk '{print $NF}')
        fi
    elif [ -f /usr/lib/libstdc++.so.6 ]; then
	    # Typical path
	    libstdcpp_path='/usr/lib/libstdc++.so.6'
    elif [ -f /usr/lib64/libstdc++.so.6 ]; then
	    # Typical path
	    libstdcpp_path='/usr/lib64/libstdc++.so.6'
    else
	    echo "Warning: Can't find libstdc++.so or ldconfig, can't verify libstdc++ version"
    fi

    while [ -n "$libstdcpp_path" ]; do
	    # Extracts the version number from the path, e.g. libstdc++.so.6.0.22 -> 6.0.22
	    # which is then compared based on the fact that release versioning and symbol versioning
	    # are aligned for libstdc++. Refs https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
	    # (i-e) GLIBCXX_3.4.<release> is provided by libstdc++.so.6.y.<release>
        libstdcpp_path_line=$(echo "$libstdcpp_path" | head -n1)
        libstdcpp_real_path=$(readlink -f "$libstdcpp_path_line")
        libstdcpp_version=$(grep -ao 'GLIBCXX_[0-9]*\.[0-9]*\.[0-9]*' "$libstdcpp_real_path" | sort -V | tail -1)
        libstdcpp_version_number=$(echo "$libstdcpp_version" | sed 's/GLIBCXX_//')
        if [ "$(printf '%s\n' "$MIN_GLIBCXX_VERSION" "$libstdcpp_version_number" | sort -V | head -n1)" = "$MIN_GLIBCXX_VERSION" ]; then
            found_required_glibcxx=1
            break
        fi
        libstdcpp_path=$(echo "$libstdcpp_path" | tail -n +2)    # remove first line
    done
else
    echo "Warning: alpine distro detected, skipping GLIBCXX check"
    found_required_glibcxx=1
fi
if [ "$found_required_glibcxx" = "0" ]; then
    echo "Warning: Missing GLIBCXX >= $MIN_GLIBCXX_VERSION! from $libstdcpp_real_path"
fi

if [ "$OS_ID" = "alpine" ]; then
    MUSL_RTLDLIST="/lib/ld-musl-aarch64.so.1 /lib/ld-musl-x86_64.so.1"
    for rtld in ${MUSL_RTLDLIST}; do
        if [ -x $rtld ]; then
            musl_version=$("$rtld" --version 2>&1 | grep "Version" | awk '{print $NF}')
            break
        fi
    done
    if [ "$(printf '%s\n' "1.2.3" "$musl_version" | sort -V | head -n1)" != "1.2.3" ]; then
        echo "Error: Unsupported alpine distribution. Please refer to our supported distro section https://aka.ms/vscode-remote/linux for additional information."
        exit 99
    fi
    found_required_glibc=1
elif [ -z "$(ldd --version 2>&1 | grep 'musl libc')" ]; then
    if [ -f /sbin/ldconfig ]; then
        # Look up path
        libc_paths=$(/sbin/ldconfig -p | grep 'libc.so.6')

        if [ "$(echo "$libc_paths" | wc -l)" -gt 1 ]; then
            libc_path=$(echo "$libc_paths" | grep "$LDCONFIG_ARCH" | awk '{print $NF}')
        else
            libc_path=$(echo "$libc_paths" | awk '{print $NF}')
        fi
    elif [ -f /usr/lib/libc.so.6 ]; then
        # Typical path
        libc_path='/usr/lib/libc.so.6'
    elif [ -f /lib64/libc.so.6 ]; then
        # Typical path (OpenSUSE)
        libc_path='/lib64/libc.so.6'
    elif [ -f /usr/lib64/libc.so.6 ]; then
        # Typical path
        libc_path='/usr/lib64/libc.so.6'
    else
        echo "Warning: Can't find libc.so or ldconfig, can't verify libc version"
    fi

    while [ -n "$libc_path" ]; do
		# Rather than trusting the output of ldd --version (which is not always accurate)
		# we instead use the version of the cached libc.so.6 file itself.
        libc_path_line=$(echo "$libc_path" | head -n1)
        libc_real_path=$(readlink -f "$libc_path_line")
        libc_version=$(cat "$libc_real_path" | sed -n 's/.*release version \([0-9]\+\.[0-9]\+\).*/\1/p')
        if [ "$(printf '%s\n' "2.28" "$libc_version" | sort -V | head -n1)" = "2.28" ]; then
            found_required_glibc=1
            break
        fi
	    libc_path=$(echo "$libc_path" | tail -n +2)    # remove first line
    done
    if [ "$found_required_glibc" = "0" ]; then
        echo "Warning: Missing GLIBC >= 2.28! from $libc_real_path"
    fi
else
    echo "Warning: musl detected, skipping GLIBC check"
    found_required_glibc=1
fi

if [ "$found_required_glibc" = "0" ] || [ "$found_required_glibcxx" = "0" ]; then
	echo "Error: Missing required dependencies. Please refer to our FAQ https://aka.ms/vscode-remote/faq/old-linux for additional information."
	# Custom exit code based on https://tldp.org/LDP/abs/html/exitcodes.html
	exit 99
fi

I’d like to note that I’m using Cursor in a corporate environment, so multiple people in this project have tried it, and everyone is having similar issues. It is possible to work around this by teaching each agent to reconfigure the environment before running any command, but I feel like this should be fixed on the IDE level.