> ## Documentation Index
> Fetch the complete documentation index at: https://docs.controlplane.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

> Solutions to common Control Plane CLI issues.

Quick solutions for common problems when using the Control Plane CLI.

## Installation and setup

<AccordionGroup>
  <Accordion title="cpln: command not found">
    **Problem**: The CLI is installed but not found when running `cpln`.

    **Solutions**:

    1. Verify the installation:

           <Tabs>
             <Tab title="bash/zsh">
               ```bash theme={null}
               which cpln
               ```
             </Tab>

             <Tab title="PowerShell">
               ```powershell theme={null}
               Get-Command cpln
               ```
             </Tab>

             <Tab title="Command Prompt">
               ```cmd theme={null}
               where cpln
               ```
             </Tab>
           </Tabs>

    2. Check if the binary is on your PATH:

           <Tabs>
             <Tab title="macOS/Linux">
               ```bash theme={null}
               echo $PATH
               ```

               Ensure `/usr/local/bin` (or your installation directory) is included.
             </Tab>

             <Tab title="PowerShell">
               ```powershell theme={null}
               $env:PATH -split ';'
               ```

               Ensure the directory containing `cpln.exe` is listed.
             </Tab>

             <Tab title="Command Prompt">
               ```cmd theme={null}
               echo %PATH%
               ```

               Ensure the directory containing `cpln.exe` is listed.
             </Tab>
           </Tabs>

    3. Reinstall the CLI:

           <Tabs>
             <Tab title="npm">
               ```bash theme={null}
               npm install -g @controlplane/cli
               ```
             </Tab>

             <Tab title="Homebrew">
               ```bash theme={null}
               brew reinstall cpln
               ```
             </Tab>

             <Tab title="Binary">
               Re-download and extract to a directory in your PATH. See [Installation](/cli-reference/installation).
             </Tab>
           </Tabs>

    4. Restart your terminal after installation.
  </Accordion>

  <Accordion title="Permission denied when installing">
    **Problem**: `npm install -g` fails with `EACCES` permission errors.

    **Solution (recommended)**: Install Node through a version manager such as [nvm](https://github.com/nvm-sh/nvm), [fnm](https://github.com/Schniz/fnm), or [Volta](https://volta.sh/). 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.

    ```bash theme={null}
    # Example with nvm
    nvm install --lts
    nvm use --lts
    npm install -g @controlplane/cli
    ```

    <Warning>
      **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.
    </Warning>

    <Accordion title="Legacy: custom prefix without sudo (only if you are NOT using nvm/fnm/Volta)">
      Use `sudo` (not recommended) or configure a custom npm prefix:

      ```bash theme={null}
      # Configure npm prefix
      mkdir -p ~/.npm-global
      npm config set prefix '~/.npm-global'
      ```

      Add to your shell profile (`~/.bashrc`, `~/.zshrc`, etc.):

      ```bash theme={null}
      export PATH=~/.npm-global/bin:$PATH
      ```

      Reload and reinstall:

      ```bash theme={null}
      source ~/.bashrc  # or ~/.zshrc
      npm install -g @controlplane/cli
      ```

      <Note>
        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.
      </Note>
    </Accordion>

    **Binary install alternative**: Move the binary to a user-writable directory instead of `/usr/local/bin`:

    ```bash theme={null}
    mkdir -p ~/bin
    mv cpln ~/bin/
    ```

    Add `~/bin` to your PATH in `~/.bashrc` or `~/.zshrc`:

    ```bash theme={null}
    export PATH="$HOME/bin:$PATH"
    ```
  </Accordion>

  <Accordion title="The CLI lingers after uninstall, or npm targets the wrong location">
    **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](https://github.com/nvm-sh/nvm) (nvm/fnm/Volta), a [Homebrew](https://brew.sh/) 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:

    ```bash theme={null}
    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:

    ```bash theme={null}
    # 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"
    ```

    <Tip>
      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`.
    </Tip>

    **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:

    ```bash theme={null}
    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)"
    ```
  </Accordion>

  <Accordion title="cpln disappears or reverts version after switching Node (nvm/fnm)">
    **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:
       ```bash theme={null}
       nvm alias default <version>     # e.g. nvm alias default 22
       ```

    2. When upgrading Node, carry your global packages forward:
       ```bash theme={null}
       nvm install <new-version> --reinstall-packages-from=<old-version>
       # or, after installing the new version:
       nvm reinstall-packages <old-version>
       ```

    3. Verify after switching:
       ```bash theme={null}
       node -v && cpln --version
       ```
  </Accordion>

  <Accordion title="A version manager is installed but Homebrew's Node keeps winning">
    **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:

    ```bash theme={null}
    # ... 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:

    ```bash theme={null}
    which node          # should be under ~/.nvm/versions/node/...
    node -v
    ```

    <Note>
      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).
    </Note>
  </Accordion>
</AccordionGroup>

## Authentication

<AccordionGroup>
  <Accordion title="Authentication failed or 403">
    **Problem**: Commands fail with authentication errors.

    **Solutions**:

    1. Check for typos in the org name:

       ```bash theme={null}
       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:
       ```bash theme={null}
       cpln login
       ```

    3. Check which profile is marked as active with a star `*`:
       ```bash theme={null}
       cpln profile get
       ```

    4. Verify the token is valid:
       ```bash theme={null}
       cpln profile token <profile-name>
       ```

    5. For service accounts, regenerate the key:

       ```bash theme={null}
       cpln serviceaccount add-key <service-account-name> --description <key-description>
       ```

           <Note>
             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).
           </Note>

       Update your profile with the new token:

       ```bash theme={null}
       cpln profile update <profile-name> --token <new-token> --gvc <gvc-name>
       ```

           <Note>
             When using `--token`, always include `--gvc` to preserve or set your default GVC context.
           </Note>
  </Accordion>

  <Accordion title="Login opens the wrong browser">
    **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](/cli-reference/get-started/authentication).
  </Accordion>

  <Accordion title="Login doesn't work in WSL2">
    **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](https://github.com/microsoft/wslg)):

    ```bash theme={null}
    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](/guides/browser-less-cli-login) with a service account token.
  </Accordion>

  <Accordion title="Wrong organization or GVC context">
    **Problem**: Commands execute in the wrong org or GVC.

    **Solutions**:

    1. Check your active profile:
       ```bash theme={null}
       cpln profile get
       ```

    2. Override for a single command:
       ```bash theme={null}
       cpln <command> --org <org-name> --gvc <gvc-name>
       ```

    3. Update your profile defaults:
       ```bash theme={null}
       cpln profile update <profile-name> --org <org-name> --gvc <gvc-name>
       ```

    4. Use a different profile:
       ```bash theme={null}
       cpln <command> --profile <profile-name>
       ```

    5. Set environment variables:
       ```bash theme={null}
       export CPLN_ORG=my-org
       export CPLN_GVC=my-gvc
       ```
  </Accordion>
</AccordionGroup>

## Connectivity and network

<AccordionGroup>
  <Accordion title="TLS certificate errors">
    **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):
       ```bash theme={null}
       cpln <command> --insecure
       ```

    4. Contact your network administrator to add Control Plane's certificate to your trust store.
  </Accordion>

  <Accordion title="Connection timeout or network errors">
    **Problem**: Commands fail with timeout or connection errors.

    **Solutions**:

    1. Check your internet connection.

    2. Verify you can reach the Control Plane API:
       ```bash theme={null}
       curl -I https://api.cpln.io/about
       ```

    3. Check if you're behind a proxy.
  </Accordion>
</AccordionGroup>

## Output and display

<AccordionGroup>
  <Accordion title="Output is truncated or incomplete">
    **Problem**: Text output doesn't show all data.

    **Solutions**:

    1. Use JSON or YAML output for complete data:
       ```bash theme={null}
       cpln <command> --output json
       cpln <command> --output yaml
       ```

    2. Increase the max results:

       ```bash theme={null}
       cpln <command> --max 100
       ```

           <Tip>
             Set `--max 0` to get all the records.
           </Tip>

    3. Use `json-slim` or `yaml-slim` for cleaner structured output:
       ```bash theme={null}
       cpln <command> --output json-slim
       ```

    See [Output Formats](/cli-reference/using-cli/output) for details.
  </Accordion>

  <Accordion title="Color codes in logs or files">
    **Problem**: Log files contain ANSI color codes.

    **Solutions**:

    1. Disable color:
       ```bash theme={null}
       cpln <command> --color=false
       ```

    2. Color is automatically disabled when stdout is not a terminal. Redirect to a file:
       ```bash theme={null}
       cpln <command> -o json > output.log
       ```
  </Accordion>
</AccordionGroup>

## Commands and operations

<AccordionGroup>
  <Accordion title="Command not found or unknown flag">
    **Problem**: CLI doesn't recognize a command or flag.

    **Solutions**:

    1. Verify you're using the correct command syntax:
       ```bash theme={null}
       cpln <command> --help
       ```

    2. Check your CLI version:
       ```bash theme={null}
       cpln --version
       ```

    3. Update to the latest version:

           <Tabs>
             <Tab title="npm">
               ```bash theme={null}
               npm update -g @controlplane/cli
               ```
             </Tab>

             <Tab title="Homebrew">
               ```bash theme={null}
               brew upgrade cpln
               ```
             </Tab>

             <Tab title="Binary">
               Download the latest binary from [Installation](/cli-reference/installation).
             </Tab>
           </Tabs>
  </Accordion>
</AccordionGroup>

## Debugging

Enable verbose or debug output to troubleshoot issues:

<CodeGroup>
  ```bash Verbose output theme={null}
  cpln <command> --verbose
  ```

  ```bash Debug mode (shows HTTP traffic) theme={null}
  cpln <command> --debug
  ```
</CodeGroup>

<Warning>
  Debug output may contain sensitive information (tokens, resource details). Use with caution and avoid sharing publicly.
</Warning>

## Getting help

If you can't resolve the issue:

* Email us at [support@controlplane.com](mailto:support@controlplane.com)
* Reach out on [Slack](https://slack.com) through the support channel

## Next steps

<CardGroup cols={2}>
  <Card title="Common Options" href="/cli-reference/using-cli/common-options" icon="sliders">
    Learn about shared CLI flags
  </Card>

  <Card title="Getting Help" href="/cli-reference/using-cli/help" icon="circle-question">
    Use the built-in help system
  </Card>
</CardGroup>
