Skip to main content
Quick solutions for common problems when using the Control Plane CLI.

Installation and setup

Problem: The CLI is installed but not found when running cpln.Solutions:
  1. Verify the installation:
    which cpln
    
  2. Check if the binary is on your PATH:
    echo $PATH
    
    Ensure /usr/local/bin (or your installation directory) is included.
  3. Reinstall the CLI:
    npm install -g @controlplane/cli
    
  4. Restart your terminal after installation.
Problem: npm install -g fails with EACCES permission errors.Solution (recommended): Install Node through a version manager such as nvm, fnm, or Volta. These install Node and its global package directory inside your home folder, so global installs never need sudo and you avoid the permission problem entirely.
# Example with nvm
nvm install --lts
nvm use --lts
npm install -g @controlplane/cli
Do not combine a custom npm config set prefix with a Node version manager. nvm, fnm, and Volta manage the global prefix per Node version themselves. Setting your own prefix (the older “install without sudo” trick below) puts global packages in a second location that the version manager doesn’t track — which leads to cpln installs that linger after uninstall and npm commands that silently target the wrong place. See the accordion “The CLI lingers after uninstall, or npm targets the wrong location” below.
Use sudo (not recommended) or configure a custom npm prefix:
# Configure npm prefix
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
Add to your shell profile (~/.bashrc, ~/.zshrc, etc.):
export PATH=~/.npm-global/bin:$PATH
Reload and reinstall:
source ~/.bashrc  # or ~/.zshrc
npm install -g @controlplane/cli
If you later adopt nvm/fnm/Volta, undo this first: npm config delete prefix, then remove the export PATH=~/.npm-global/bin:$PATH line from your shell profile. Otherwise the two prefixes will conflict.
Binary install alternative: Move the binary to a user-writable directory instead of /usr/local/bin:
mkdir -p ~/bin
mv cpln ~/bin/
Add ~/bin to your PATH in ~/.bashrc or ~/.zshrc:
export PATH="$HOME/bin:$PATH"
Problem: One or more of the following:
  • npm uninstall -g @controlplane/cli prints up to date (or removed 0 packages), yet cpln still runs.
  • npm update -g @controlplane/cli reports success but cpln --version doesn’t change.
  • After installing, cpln: command not found in a new terminal even though the install succeeded.
Cause: You have more than one Node on your machine — commonly a version manager (nvm/fnm/Volta), a Homebrew Node, and/or a custom ~/.npm-global prefix. cpln is a #!/usr/bin/env node script, so it runs under whichever node is first on your PATH, and npm -g reads/writes the prefix of the specific npm you invoke. When those disagree, npm manages one location while cpln actually lives in another — so uninstall and update appear to do nothing.Step 1 — See what you actually have. Run every line; mismatches are the diagnosis:
which -a node npm cpln          # every copy on PATH, in priority order
node -v                         # which node actually runs
npm -v
npm config get prefix           # where THIS npm installs global packages
readlink -f "$(command -v cpln)" # where the cpln on PATH physically lives
If npm config get prefix does not contain the same directory as the resolved cpln path, that is exactly why uninstall/update is a no-op — npm is pointed at the wrong prefix.Step 2 — Remove every stale copy. Uninstall from each prefix that has it, then delete any leftover symlink directly:
# Run the uninstall once per Node/prefix that contains it.
npm uninstall -g @controlplane/cli

# If a cpln still resolves, remove the orphaned symlink + package by hand:
rm -f "$(command -v cpln)" "$(command -v docker-credential-cpln 2>/dev/null)"
hash -r                          # clear the shell's cached command paths (zsh/bash)
which -a cpln || echo "cpln fully removed"
A custom-prefix install lives at ~/.npm-global/{bin,lib/node_modules}/@controlplane. A Homebrew install lives under /opt/homebrew/lib/node_modules (Apple Silicon) or /usr/local/lib/node_modules (Intel). An nvm install lives under ~/.nvm/versions/node/<version>/lib/node_modules.
Step 3 — Reinstall into the prefix you intend to use. Whatever node you want must be first on PATH before you install, so the install lands where you’ll run it:
nvm use --lts          # or: nvm use <version> — selects the node you want
npm install -g @controlplane/cli
cpln --version         # confirm it runs from the expected location
readlink -f "$(command -v cpln)"
Problem: cpln worked, then vanished or reverted to an old version after running nvm use, nvm install, or opening a new shell.Cause: Version managers keep a separate global package set per Node version. Installing @controlplane/cli under Node 20 does not make it available under Node 22, and switching versions switches which cpln (if any) is on PATH.Solutions:
  1. Install the CLI under the Node version you actually use, then pin that version as the default so new shells use it:
    nvm alias default <version>     # e.g. nvm alias default 22
    
  2. When upgrading Node, carry your global packages forward:
    nvm install <new-version> --reinstall-packages-from=<old-version>
    # or, after installing the new version:
    nvm reinstall-packages <old-version>
    
  3. Verify after switching:
    node -v && cpln --version
    
Problem: You installed nvm/fnm, but which node still points at /opt/homebrew/bin/node (or /usr/local/bin/node), so your version manager’s Node — and the cpln installed under it — is ignored.Cause: PATH order. Your shell startup file loads the version manager, but a later line re-prepends Homebrew’s bin to PATH (for example export PATH="/opt/homebrew/bin:$PATH", or Homebrew’s shellenv), so Homebrew’s node ends up ahead of the version manager’s.Solution: Make the version manager activate last in your ~/.zshrc / ~/.bashrc, after any line that prepends Homebrew. With nvm, the robust form is to activate the default version and push its bin to the front of PATH at the end of the file:
# ... all other PATH exports, including Homebrew, above this ...

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Activate the default Node and ensure it wins over Homebrew on PATH.
# (nvm use swaps the version in place and will not re-front itself.)
command -v nvm >/dev/null && nvm use default --silent >/dev/null 2>&1
[ -n "$NVM_BIN" ] && export PATH="$NVM_BIN:$PATH"
Open a new terminal and confirm:
which node          # should be under ~/.nvm/versions/node/...
node -v
Keeping Homebrew’s Node installed is fine — it just must not shadow the version you intend to use. If you don’t need it, brew uninstall node (check first that no other Homebrew formula depends on it).

Authentication

Problem: Commands fail with authentication errors.Solutions:
  1. Check for typos in the org name:
    cpln profile get
    
    Verify the org value is correct. A 403 often means you’re trying to access an org that doesn’t exist or that you don’t have access to.
  2. Re-authenticate:
    cpln login
    
  3. Check which profile is marked as active with a star *:
    cpln profile get
    
  4. Verify the token is valid:
    cpln profile token <profile-name>
    
  5. For service accounts, regenerate the key:
    cpln serviceaccount add-key <service-account-name> --description <key-description>
    
    Make sure the service account is assigned to a group that has the necessary permissions to access and manage resources (e.g. the superusers group).
    Update your profile with the new token:
    cpln profile update <profile-name> --token <new-token> --gvc <gvc-name>
    
    When using --token, always include --gvc to preserve or set your default GVC context.
Problem: cpln login opens a browser you don’t use.Solutions:
  1. Copy the URL from the terminal and paste it into your preferred browser.
  2. Change your system’s default browser (OS-specific).
  3. Use a service account token instead of interactive login. See Authentication.
Problem: cpln login opens a localhost URL that doesn’t work in your Windows browser.Cause: The localhost URL points to the WSL2 instance, not Windows.Solution: Install a browser in WSL2 (requires WSLg):
cd /tmp
sudo wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
sudo apt install --fix-broken -y
sudo dpkg -i google-chrome-stable_current_amd64.deb
After installation, Chrome appears in your Windows Start menu under the distro name (e.g., Ubuntu → Google Chrome). Run cpln login, copy the localhost URL from the terminal, and paste it into your WSL2 Chrome.Alternative: Use browser-less login with a service account token.
Problem: Commands execute in the wrong org or GVC.Solutions:
  1. Check your active profile:
    cpln profile get
    
  2. Override for a single command:
    cpln <command> --org <org-name> --gvc <gvc-name>
    
  3. Update your profile defaults:
    cpln profile update <profile-name> --org <org-name> --gvc <gvc-name>
    
  4. Use a different profile:
    cpln <command> --profile <profile-name>
    
  5. Set environment variables:
    export CPLN_ORG=my-org
    export CPLN_GVC=my-gvc
    

Connectivity and network

Problem: Commands fail with TLS/SSL errors.Solutions:
  1. Verify your system’s certificate trust store is up to date.
  2. Check if you’re behind a corporate proxy or firewall that intercepts TLS.
  3. As a temporary workaround (not recommended for production):
    cpln <command> --insecure
    
  4. Contact your network administrator to add Control Plane’s certificate to your trust store.
Problem: Commands fail with timeout or connection errors.Solutions:
  1. Check your internet connection.
  2. Verify you can reach the Control Plane API:
    curl -I https://api.cpln.io/about
    
  3. Check if you’re behind a proxy.

Output and display

Problem: Text output doesn’t show all data.Solutions:
  1. Use JSON or YAML output for complete data:
    cpln <command> --output json
    cpln <command> --output yaml
    
  2. Increase the max results:
    cpln <command> --max 100
    
    Set --max 0 to get all the records.
  3. Use json-slim or yaml-slim for cleaner structured output:
    cpln <command> --output json-slim
    
See Output Formats for details.
Problem: Log files contain ANSI color codes.Solutions:
  1. Disable color:
    cpln <command> --color=false
    
  2. Color is automatically disabled when stdout is not a terminal. Redirect to a file:
    cpln <command> -o json > output.log
    

Commands and operations

Problem: CLI doesn’t recognize a command or flag.Solutions:
  1. Verify you’re using the correct command syntax:
    cpln <command> --help
    
  2. Check your CLI version:
    cpln --version
    
  3. Update to the latest version:
    npm update -g @controlplane/cli
    

Debugging

Enable verbose or debug output to troubleshoot issues:
cpln <command> --verbose
Debug output may contain sensitive information (tokens, resource details). Use with caution and avoid sharing publicly.

Getting help

If you can’t resolve the issue:

Next steps

Common Options

Learn about shared CLI flags

Getting Help

Use the built-in help system