coreybutler/nvm-windows · error

failed to elevate permissions to create symlink

Error message

failed to elevate permissions to create symlink

What it means

Emitted by `nvm use` when the elevated helper (elevate.cmd / elevatedRun path) could not successfully create the NVM_SYMLINK junction to the selected version. Creating the symlink requires elevation on standard NTFS setups, so this means the elevation attempt failed or returned non-success (ok == false) after trying runElevated.

Source

Thrown at src/nvm.go:1231

				ok, err = elevatedRun("rmdir", filepath.Clean(env.symlink))
				// ok, err = runElevated(fmt.Sprintf(`"%s" cmd /C rmdir "%s"`, filepath.Join(env.root, "elevate.cmd"), filepath.Clean(env.symlink)))
				reloadable := true
				if len(reload) > 0 {
					reloadable = reload[0]
				}
				if err != nil {
					status <- Status{Err: err, Done: true}
				} else if reloadable {
					use(version, cpuarch, false)
					return
				}
			} else {
				status <- Status{Err: err, Done: true}
			}
		}
		if !ok {
			status <- Status{Err: fmt.Errorf("failed to elevate permissions to create symlink"), Done: true}
		}

		// Use the assigned CPU architecture
		cpuarch = arch.Validate(cpuarch)
		nodepath := filepath.Join(env.root, "v"+version, "node.exe")
		node32path := filepath.Join(env.root, "v"+version, "node32.exe")
		node64path := filepath.Join(env.root, "v"+version, "node64.exe")
		node32exists := file.Exists(node32path)
		node64exists := file.Exists(node64path)
		nodeexists := file.Exists(nodepath)
		if node32exists && cpuarch == "32" { // user wants 32, but node.exe is 64
			if nodeexists {
				utility.Rename(nodepath, node64path) // node.exe -> node64.exe
			}
			utility.Rename(node32path, nodepath) // node32.exe -> node.exe
		}
		if node64exists && cpuarch == "64" { // user wants 64, but node.exe is 32
			if nodeexists {

View on GitHub (pinned to 5b18223ca1)

Solutions

  1. Re-run `nvm use <version>` from an elevated terminal (Run as administrator) so no UAC elevation round-trip is needed
  2. Accept the UAC prompt when it appears; if it never appears, check that elevate.cmd exists in the NVM root
  3. Grant the user SeCreateSymbolicLinkPrivilege via Local Security Policy (secpol.msc) and re-run
  4. Ensure NVM_HOME/NVM_SYMLINK are on a local NTFS volume
  5. Add an antivirus exclusion for the NVM root if elevate.cmd is being blocked

Example fix

# before (standard shell, UAC denied)
nvm use 20.11.0
# -> failed to elevate permissions to create symlink

# after (elevated PowerShell)
Start-Process powershell -Verb RunAs -ArgumentList 'nvm use 20.11.0'
Defensive patterns

Strategy: try-catch

Try / catch

if err := useVersion(version, arch); err != nil {
    if strings.Contains(err.Error(), "failed to elevate permissions") {
        // retry from an already-elevated context or surface a UAC hint to the user
        log.Fatal("run from an administrator shell, or accept the UAC prompt")
    }
}

Prevention

When it happens

Trigger: Calling `nvm use <version>` where os.Symlink creation fails and the runElevated fallback (via the bundled elevate.cmd shim) reports failure: UAC prompt declined, elevate.cmd missing from NVM root, egress blocked by group policy, or symlink privileges not granted and elevation refused.

Common situations: User clicks 'No' on the UAC dialog; corporate policy (SeCreateSymbolicLinkPrivilege removed and UAC auto-deny); antivirus quarantining elevate.cmd; NVM root on a network/FAT volume that does not support symlinks; running in a restricted service account or CI without an interactive desktop for UAC.

Related errors


AI-assisted analysis of coreybutler/nvm-windows@5b18223ca1 (2026-08-15). Data as JSON: /api/errors/72c44dff558b5511. Report an issue: GitHub.