Containers

Master the ArgoCD CLI: Complete Command Reference and Workflows

Most ArgoCD users learn the CLI from snippets. The official command reference is dry, the popular cheat sheets miss recent 3.x additions, and tutorials usually focus on one workflow each. This guide pulls the whole surface together: every top-level command, real terminal outputs from a tested cluster, decision tables that tell you when CLI beats UI, and the 3.x features that have landed since most existing guides were written.

Original content from computingforgeeks.com - post 167312

What you get out of this article: a working mental model of the argocd binary, copy-paste recipes for the application lifecycle, repo and cluster management, ApplicationSets, account tokens, output formats for jq pipelines, shell completion, the new CLI plugin system, and admin commands. Each section has output captured on a real Kubernetes cluster running ArgoCD 3.3.x against a CLI 3.3.8 client.

Verified working: May 2026 on Kubernetes 1.35 with ArgoCD server 3.3.9 and CLI 3.3.8, tested across Linux, macOS Apple Silicon, and Windows 11.

When to use the ArgoCD CLI vs the UI vs the API

The CLI, the web UI, and the gRPC/REST API all hit the same backend. Picking the right interface saves time and keeps audit trails clean.

TaskBest interfaceWhy
One-off sync, diff, rollback during an incidentCLIFaster than clicking; keeps shell history as audit log
Visual exploration of resources, sync waves, hooksUITree view shows hierarchy that app get -o tree only hints at
CI/CD pipelines and automationCLIIdempotent, scriptable, exit codes for failure detection
Bulk operations across 50+ appsCLI with --selector or --projectUI has no batch operation; CLI takes label and project filters
Drift detection and PR diff commentsCLI in CINative exit codes (0/1/2) make scripting clean
Realtime troubleshooting (events, logs)UIStreaming view with filters and resource graph
Programmatic integration into custom toolingAPIgRPC and REST are versioned; CLI output formats can shift

A working pattern that scales: use the UI to explore and triage, use the CLI to act, and use the API only when wrapping ArgoCD inside another tool.

The 17 top-level commands at a glance

Run argocd --help against any 3.x server and you get the same map. Treat this table as the page-jump for the rest of the guide.

argocd --help output showing all 17 top-level commands account admin app appset etc
CommandPurposeAuth required
accountManage account settings, tokens, passwordYes (server)
adminDirect-cluster commands (export/import, RBAC validation, dashboard)kubectl access (not server)
appManage applications (24 subcommands cover the full lifecycle)Yes (server)
appsetManage ApplicationSets (list, create, get, delete, generate)Yes (server)
certManage repo TLS certificates and SSH known hostsYes (server)
clusterRegister and manage external Kubernetes clustersYes (server) plus kubectl on the target cluster
completionEmit shell completion for bash, zsh, fishNo
configureManage local CLI configurationNo
contextSwitch between server contextsNo
gpgManage GPG keys for commit signature verificationYes (server)
loginLog in to an ArgoCD server (password, SSO, JWT, K8s API)n/a
logoutEnd a sessionn/a
projManage AppProjects (RBAC and tenancy boundaries)Yes (server)
reloginRefresh the current session tokenn/a
repoManage repository connections (Git, Helm, OCI)Yes (server)
repocredsManage credential templates (one set of creds for many repos)Yes (server)
versionPrint client and server versions, plus toolingServer is optional (use --client)

ArgoCD 3.1 added a kubectl-style plugin system on top of these. Any executable in your PATH that begins with argocd- shows up as a custom subcommand. The plugin section later covers limits and a working example.

Quick install verification

If argocd is already on your PATH, jump to the next section. Otherwise the fastest path on each platform looks like this. Detect the latest release tag and install the binary in one block:

export ARGOCD_VERSION=$(curl -s https://api.github.com/repos/argoproj/argo-cd/releases/latest \
  | grep tag_name | head -1 | sed 's/.*"\(v[^"]*\)".*/\1/') #https://github.com/argoproj/argo-cd/releases
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
curl -sSL -o argocd \
  "https://github.com/argoproj/argo-cd/releases/download/${ARGOCD_VERSION}/argocd-linux-${ARCH}"
sudo install -m 555 argocd /usr/local/bin/argocd
rm argocd

On macOS Apple Silicon, the cleanest install is Homebrew because brew installs land outside the quarantine flag, so Gatekeeper does not pop a “damaged app” dialog:

brew install argocd
argocd version --client

On Windows, Scoop or Chocolatey both work. With Scoop the steps are scoop install argocd followed by argocd version --client in a fresh terminal so PATH propagates. Once any of these complete, confirm the install with the version check:

ArgoCD CLI version output showing client v3.3.8 and server v3.3.9 with multiple contexts

Notice the client (3.3.8) is one patch behind the server (3.3.9). That is fine. The skew rule is simple: client major plus minor must match the server. A client one patch behind a server is the most common live state because you upgrade clusters faster than developer laptops.

Authentication and contexts

Every command except version --client and completion needs an authenticated session. ArgoCD supports four login modes: username and password, SSO (OIDC, SAML), bearer JWT tokens for service accounts, and direct Kubernetes API server access for in-cluster scripts.

The first login on a fresh install starts with the auto-generated admin password:

kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath='{.data.password}' | base64 -d
echo
argocd login argocd.lab.local --username admin \
  --password 'paste-the-decoded-secret-here' --insecure --grpc-web

The output confirms the session is stored:

'admin:login' logged in successfully
Context 'argocd.lab.local' updated

The --insecure flag skips certificate verification because the demo cluster uses a self-signed cert. The --grpc-web flag matters when ArgoCD sits behind an ingress that only speaks HTTP/1.1 (AWS ALB, most Nginx ingresses without TLS passthrough). Once set during login it persists in ~/.config/argocd/config, so future commands inherit it without repeating the flag.

Right after the first login, rotate the admin password. The CLI ships a helper:

argocd account update-password \
  --account admin \
  --current-password 'paste-the-old-secret-here' \
  --new-password 'paste-a-strong-passphrase-here'

Working against multiple ArgoCD servers? argocd context manages them. Each argocd login appends an entry; switching is one command. The current context shows the asterisk:

argocd context

Two contexts are registered, the second is active:

CURRENT  NAME              SERVER
         localhost:8080    localhost:8080
*        argocd.lab.local  argocd.lab.local

Switch with argocd context localhost:8080 and remove with argocd context localhost:8080 --delete. The whole config sits in one YAML file at ~/.config/argocd/config, which means you can sync it across workstations the same way you sync ~/.kube/config. Override the location with --config /path/to/file or the ARGOCD_CONFIG_DIR environment variable.

For automation, generate a JWT bearer token instead of passing a password. First grant the local account API key capability, then mint a scoped token with an explicit expiry:

kubectl -n argocd patch configmap argocd-cm --type merge \
  -p '{"data":{"accounts.ci-bot":"apiKey"}}'
argocd account generate-token \
  --account ci-bot \
  --expires-in 30d \
  --id ci-bot-2026-05

Decoding the token shows what ArgoCD signs into the JWT payload:

{
    "iss": "argocd",
    "sub": "ci-bot:apiKey",
    "exp": 1780180806,
    "nbf": 1777588806,
    "iat": 1777588806,
    "jti": "pillar-demo"
}

The jti matches the --id you passed, the exp is the Unix timestamp when the token stops working, and sub tracks which account it belongs to. Always set --expires-in explicitly. The default is no expiry, which is an audit risk on long-lived tokens.

Existing tokens for an account are visible via argocd account get:

argocd account get --account ci-bot

The output lists capabilities and active tokens with issue and expiry timestamps:

Name:               ci-bot
Enabled:            true
Capabilities:       apiKey

Tokens:
ID           ISSUED AT                  EXPIRING AT
pillar-demo  2026-05-01T01:40:06+03:00  2026-05-31T01:40:06+03:00

Use the token in CI by exporting ARGOCD_AUTH_TOKEN, or by passing --auth-token on every command. SSO setups (Dex, Keycloak, GitHub OIDC) follow a similar shape but with argocd login --sso; that flow needs full coverage of group-claim mapping and is the subject of a dedicated guide in this series.

The application lifecycle from the CLI

This is where most reader time goes. We will walk one Application from creation to rollback using the canonical Guestbook example. Set a few variables to keep the rest of the section clean:

export APP=guestbook
export REPO=https://github.com/argoproj/argocd-example-apps.git
export DEST=https://kubernetes.default.svc

Creating an Application

The app create command supports plain manifests, Kustomize directories, Helm charts from Git, Helm charts from OCI registries (added in 3.1), and multi-source applications. The simplest form points at a Git path and lets ArgoCD auto-detect:

argocd app create ${APP} \
  --repo ${REPO} \
  --path guestbook \
  --dest-namespace default \
  --dest-server ${DEST} \
  --revision HEAD

The expected confirmation:

application 'guestbook' created

For a Helm chart pulled directly from a Bitnami OCI repo, the syntax shifts to --helm-chart and --revision:

argocd app create helm-nginx \
  --repo https://charts.bitnami.com/bitnami \
  --helm-chart nginx --revision 21.0.4 \
  --dest-namespace web --dest-server ${DEST} \
  --helm-set service.type=ClusterIP

For a directory of plain manifests in a subfolder, add --directory-recurse. For Kustomize, ArgoCD auto-detects kustomization.yaml and applies it. For multi-source apps (since 2.6) repeat --source blocks; this is how a single Application can pull manifests from one repo and Helm values from another.

Listing and inspecting Applications

After creation, the new app shows up immediately:

argocd app list

The fresh Application appears in the list with its current state:

NAME              CLUSTER                         NAMESPACE  PROJECT  STATUS     HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                 PATH       TARGET
argocd/guestbook  https://kubernetes.default.svc  default    default  OutOfSync  Missing  Manual      <none>      https://github.com/argoproj/argocd-example-apps.git  guestbook  HEAD

The status is OutOfSync because the resources have not been applied yet, and the health is Missing for the same reason. Drill into the resources with argocd app get:

argocd app get ${APP}

The detailed view shows source, sync window, sync status, health, and the resource breakdown:

Name:               argocd/guestbook
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://argocd.lab.local/applications/guestbook
Source:
- Repo:             https://github.com/argoproj/argocd-example-apps.git
  Target:           HEAD
  Path:             guestbook
SyncWindow:         Sync Allowed
Sync Policy:        Manual
Sync Status:        OutOfSync from HEAD (723b86e)
Health Status:      Missing

GROUP  KIND        NAMESPACE  NAME          STATUS     HEALTH   HOOK  MESSAGE
       Service     default    guestbook-ui  OutOfSync  Missing
apps   Deployment  default    guestbook-ui  OutOfSync  Missing

The get command takes -o tree, -o yaml, -o json, and -o wide. Tree output is the most readable for hierarchies; JSON is what you pipe into jq for scripting. The same OutOfSync app shown after a successful sync looks like this:

ArgoCD app list, app get and app history showing Guestbook synced and healthy

Diffing target vs live

Before applying, see exactly what will change with argocd app diff. Without arguments it compares the desired state (Git) to the live state (cluster). With --revision it compares to a specific commit, branch, or tag without applying:

argocd app diff ${APP}
echo "exit code: $?"

The output prints unified diffs for each resource, grouped by kind. Greater-than markers indicate additions, lower-than would indicate removals:

argocd app diff Guestbook output showing Service and Deployment manifests to be applied

Pay attention to the exit code. argocd app diff follows three-state semantics: 0 means no diff, 1 means a diff was found, and 2 means an error (auth, network, missing app). This is the foundation of CI workflows that gate merges on a clean diff. To suppress the non-zero exit when a diff is expected (a PR review pipeline), pass --exit-code=false.

Syncing and waiting

The verb that actually changes the cluster is argocd app sync. Default behavior applies the diff, blocks until the operation completes, then exits. The output shows each resource transitioning from OutOfSync to Synced:

argocd app sync ${APP}

Watch the resources flip from OutOfSync/Missing to Synced/Healthy as the controller applies them:

2026-05-01T01:37:52+03:00            Service     default          guestbook-ui  OutOfSync  Missing              service/guestbook-ui created
2026-05-01T01:37:52+03:00   apps  Deployment     default          guestbook-ui  OutOfSync  Missing              deployment.apps/guestbook-ui created
2026-05-01T01:37:52+03:00            Service     default          guestbook-ui    Synced  Healthy              service/guestbook-ui created

Sync Status:        Synced to HEAD (723b86e)
Health Status:      Progressing

Operation:          Sync
Sync Revision:      723b86e01bea11dcf72316cb172868fcbf05d69e
Phase:              Succeeded
Start:              2026-05-01 01:37:52 +0300 EAT
Finished:           2026-05-01 01:37:52 +0300 EAT
Duration:           0s
Message:            successfully synced (all tasks run)

Sync without health is half a deploy. The companion command argocd app wait blocks until the application reaches a target state, with --health, --sync, --suspended, --degraded, and --timeout flags. Default behavior waits for both Synced and Healthy:

argocd app wait ${APP} --health --timeout 300

Health states follow a strict priority order: Healthy beats Suspended beats Progressing beats Missing beats Degraded beats Unknown. A CI job that runs sync then wait is the most common automated deploy primitive in ArgoCD ecosystems. The full flag matrix for app sync (over thirty flags including --prune, --force, --server-side, --apply-out-of-sync-only, --retry-limit, sync waves, and the five hook types) is the topic of a dedicated guide in this series; the table here covers the ones you reach for daily.

FlagWhat it doesWhen to use
--pruneDelete resources that exist in the cluster but not in GitCleanup syncs after removing manifests from a repo
--forceRecreate resources instead of using kubectl applyResolve immutable field errors (selector changes, etc.)
--dry-runPrint what would change, do not applyProduction safety check before a real sync
--server-sideUse Server-Side Apply (proper field ownership)HPA-managed replicas, large manifests, cross-controller conflicts
--asyncFire and exit; do not wait for the operationCI fan-out across many apps
--apply-out-of-sync-onlySkip resources already in syncLarge apps where most resources are unchanged
--revision XOne-time override of the target revisionRollback by syncing to an older commit, or testing a branch
--selector key=valueSync only matching resourcesSurgical syncs during incidents

History and rollback

Every successful sync writes an entry to the application history. Read it back with argocd app history:

argocd app history ${APP}

Each row is a deployment with a numeric ID, a timestamp, and the Git revision:

SOURCE  https://github.com/argoproj/argocd-example-apps.git
ID      DATE                           REVISION
0       2026-05-01 01:37:52 +0300 EAT  HEAD (723b86e)

To roll back, pass the history ID. The rollback updates the cluster to that revision but does not change the Application’s targetRevision:

argocd app rollback ${APP} 0

Omit the ID and ArgoCD rolls back one revision. Add --prune if the older revision had fewer resources than the current one. After a rollback, run argocd app diff against your Git revision to see whether the live state has drifted from what Git wants. The next push to targetRevision will move the live state forward again unless you also revert the Git change.

Deleting an Application

Deleting an Application by default cascades to its resources. ArgoCD adds a finalizer when --cascade=true (the default), waits for the controller to clean child resources, then removes the Application object. To leave the cluster resources behind and only remove the Application record, pass --cascade=false:

argocd app delete ${APP} --cascade=true --yes

If a delete hangs, the cause is almost always a stuck finalizer on a resource the cluster cannot reap. Inspect the Application with argocd app get and look at the conditions. The escape hatch is argocd app patch to remove the finalizer manually, but only after you understand why ArgoCD is unable to reap.

Repositories, clusters, and projects

Three command groups manage ArgoCD’s connection inventory: repo for Git, Helm, and OCI sources, cluster for the Kubernetes targets ArgoCD deploys into, and proj for the AppProject objects that define RBAC and tenancy boundaries.

Adding repositories

Public Git repos do not need credentials, but registering them makes them visible in the UI and lets you scope per-repo settings:

argocd repo add https://github.com/argoproj/argocd-example-apps

Confirmation that ArgoCD now tracks the repo:

Repository 'https://github.com/argoproj/argocd-example-apps' added

For a private GitHub repo, supply a personal access token. For a private GitLab project, the username is typically gitlab+deploy-token-NNN and the password is the deploy token value:

argocd repo add https://github.com/myorg/private-repo.git \
  --username my-bot --password 'paste-your-github-pat-here'

argocd repo add https://gitlab.example.com/team/app.git \
  --username gitlab+deploy-token-42 \
  --password 'deploy-token-secret'

SSH-based repositories take a private key path. The --insecure-ignore-host-key flag skips known-hosts validation and is only safe in trusted environments:

argocd repo add [email protected]:myorg/private-repo.git \
  --ssh-private-key-path ~/.ssh/argocd_ed25519 \
  --insecure-ignore-host-key

Listing shows status and credential type:

argocd repo list

The status column shows whether ArgoCD reached the repo successfully on its last poll:

TYPE  NAME  REPO                                             INSECURE  OCI    LFS    CREDS  STATUS      MESSAGE  PROJECT
git         https://github.com/argoproj/argocd-example-apps  false     false  false  false  Successful           

For organisations with many repos under the same provider, register a credential template once via argocd repocreds add with a wildcard URL prefix, and individual repos under that prefix inherit the credentials automatically.

Registering external clusters

By default, ArgoCD deploys into the cluster it runs in (https://kubernetes.default.svc). To deploy into other clusters, register them with argocd cluster add. The command reads from your kubeconfig and creates an argocd-manager ServiceAccount in the target cluster’s kube-system namespace, binds it to cluster-admin, and stores the resulting token in ArgoCD:

argocd cluster add staging-eks --kubeconfig ~/.kube/config

For least-privilege setups, supply a pre-created service account with scoped permissions and pass --service-account my-argocd-sa --system-namespace my-namespace. Since ArgoCD 2.4, on Kubernetes 1.24+, the command creates a non-expiring ServiceAccount token Secret rather than relying on the legacy auto-mounted token.

List clusters and watch the connection state:

argocd cluster list

A fresh install lists only the in-cluster target until at least one Application points elsewhere:

SERVER                          NAME        VERSION  STATUS   MESSAGE
https://kubernetes.default.svc  in-cluster           Unknown  Cluster has no applications and is not being monitored.

The cluster shows up as Unknown until it has an Application targeting it. After the first sync, the version and message fields populate. argocd cluster rotate-auth rotates the credential without re-running add, useful when an SA token leaks and you need to invalidate without disturbing applications.

Projects as RBAC and tenancy boundaries

An AppProject is the RBAC boundary in ArgoCD. Each Application belongs to exactly one project. Projects whitelist source repos, destination clusters, destination namespaces, and resource kinds. Mismatches produce the famous “app is not permitted” error which originates entirely from project misconfig.

argocd proj create platform \
  --description "Platform team apps" \
  --src https://github.com/myorg/platform-apps \
  --dest https://kubernetes.default.svc,platform \
  --allow-cluster-resource '*/Namespace'

Inspect a project with argocd proj get NAME; tighten constraints with argocd proj add-source, argocd proj add-destination, and argocd proj add-namespace-resource. The default project (default) accepts any source and any destination, which is fine for a single-team lab but unsafe in shared environments.

ApplicationSets via the CLI

An ApplicationSet generates many Applications from a single template plus a generator (Git folders, cluster list, matrix combinations, lists, and so on). The CLI surface is small: list, get, create, delete, and generate:

argocd appset list
argocd appset create my-appset.yaml --upsert
argocd appset get production
argocd appset generate my-appset.yaml --dry-run

Two flags carry most of the weight. --upsert makes create idempotent: if the ApplicationSet already exists it is updated rather than failing. --dry-run on generate shows the list of Applications the controller would produce without touching the cluster, which is invaluable for reviewing template changes before a merge. For a deeper look at multi-cluster generators and rollout strategies, the ArgoCD ApplicationSet multi-cluster guide on this site walks through Git, Cluster, and Matrix generators end-to-end.

Certificates, GPG, and configuration

Three less-frequented command groups handle trust and local CLI state. argocd cert manages TLS certificates and SSH known hosts that ArgoCD trusts when fetching from repositories. Self-signed Git servers and internal SSH hosts are the common reasons to use it:

argocd cert add-tls git.internal.lan --from /etc/ssl/certs/internal-ca.pem
argocd cert add-ssh --batch git.internal.lan ssh-rsa AAAA...
argocd cert list

argocd gpg manages GPG keys for signature verification on commits. If a project requires signed commits, ArgoCD will refuse to sync revisions whose commit signatures cannot be verified against keys in this store:

argocd gpg add --from gpg-pubkey.asc
argocd gpg list

argocd configure covers local CLI configuration that does not need server input, currently the prompts-enabled flag and a few logging defaults. argocd version --output yaml prints client and server versions in machine-readable form, useful in a CI step that fails the build when the skew widens too far.

Output formats and shell completion

Most read-only commands (app list, app get, cluster list, repo list) accept -o json, -o yaml, or -o wide. The app get command also supports -o tree, which prints the resource hierarchy in a way that works well with copy-paste into a chat. JSON output is the input most automation needs:

argocd app list -o json | jq -r '.[] | select(.status.sync.status=="OutOfSync") | .metadata.name'
argocd app get guestbook -o json | jq -r '.status.resources[] | "\(.kind)/\(.name): \(.status)"'

Two practical caveats. First, output-format support is not uniform across every command (the project tracks this in the upstream issue tracker). When a command does not list json in its -o options, fall back to the underlying API. Second, some commands intermix progress lines with structured output. Strip the prefix lines with jq -R or save to a file and re-parse if your pipeline breaks.

Shell completion is a quick quality-of-life win:

# bash
argocd completion bash | sudo tee /etc/bash_completion.d/argocd > /dev/null

# zsh
argocd completion zsh > "${fpath[1]}/_argocd"

# fish
argocd completion fish > ~/.config/fish/completions/argocd.fish

Once loaded, completion offers app names, cluster names, repo URLs, project names, and flags as you type. Type argocd app sy then Tab and the shell completes sync; type argocd app sync <TAB> and you get the list of registered Applications.

CLI plugins (ArgoCD 3.1+)

Since 3.1, the argocd binary follows the same plugin pattern as kubectl. Any executable in your PATH whose name starts with argocd- becomes available as a custom subcommand. Build a tiny one to see the discovery in action:

cat << 'PLUGIN' | sudo tee /usr/local/bin/argocd-hello > /dev/null
#!/usr/bin/env bash
echo "argocd-hello plugin running"
echo "argv: $*"
PLUGIN
sudo chmod +x /usr/local/bin/argocd-hello

argocd hello world from cli

The plugin script runs and receives its arguments cleanly:

argocd-hello plugin running
argv: world from cli

Two limits matter. Plugins cannot override existing top-level commands; argocd-version would never run because the built-in version wins. Plugins also cannot add subcommands under existing groups; an argocd-cluster plugin would be ignored because the built-in cluster already owns that namespace. Use plugins for net-new top-level commands like argocd-drift-report, argocd-cost, or argocd-promote wrappers around existing CI flows.

Account management and tokens

Account management lives under argocd account. The most-used commands in production:

argocd account list
argocd account get --account ci-bot
argocd account get-user-info
argocd account update-password
argocd account generate-token --account ci-bot --expires-in 30d --id ci-2026-05
argocd account delete-token --account ci-bot --id ci-2026-04
argocd account bcrypt --password 'NewPassword123'

The diagnostic command in this group is argocd account get-user-info. It returns the identity ArgoCD recognises for your current session, including any group claims an SSO provider asserted. When sync fails with “permission denied”, this is the first thing to check; the second is whether the groups it lists match the policy in argocd-rbac-cm.

argocd account get-user-info

The result mirrors what ArgoCD will use for RBAC decisions on every subsequent call:

Logged In: true
Username: admin
Issuer: argocd
Groups: 

argocd account bcrypt is the helper for setting an admin password declaratively. Pipe the bcrypt hash into the argocd-secret Kubernetes Secret as admin.password and ArgoCD picks it up on the next pod restart, no update-password call needed. This pattern is how GitOps installs of ArgoCD itself manage the bootstrap admin without storing plain passwords in Git.

Admin commands and the cluster-side surface

Everything under argocd admin bypasses the API server and talks to Kubernetes directly using your kubeconfig. This is the survival kit when the API server is broken, when you need a backup, or when you want to validate RBAC offline.

argocd admin initial-password               # bootstrap admin password
argocd admin dashboard --port 8080          # local UI without ingress
argocd admin export > backup.yaml           # full state backup
argocd admin import - < backup.yaml         # restore
argocd admin settings validate --load-cluster-settings
argocd admin settings rbac validate --policy-file policy.csv
argocd admin settings rbac can ROLE ACTION RESOURCE [SUB] --namespace argocd

The standout is argocd admin settings rbac can. It simulates an RBAC decision without making the real API call, which is the fastest way to debug "who can do what" questions:

argocd admin settings rbac can role:readonly get applications --namespace argocd
argocd admin settings rbac can role:readonly create applications --namespace argocd
argocd admin settings rbac can role:admin sync applications 'default/guestbook' --namespace argocd

Three answers, one per query, in order: read-only can read but not create, admin can sync the named app:

Yes
No
Yes

Backups via argocd admin export capture Applications, AppProjects, repos, clusters, accounts, RBAC, and settings into one YAML stream. Practical pattern: cron-redirect the output into a Git repo and let history serve as a recovery point. For a tested disaster recovery walkthrough using export and import, see the existing Kubernetes etcd backup and restore guide for the underlying state plane and pair it with argocd admin export for the ArgoCD layer.

Troubleshooting quick lookup

Most CLI errors fall into four buckets. The exact-string heading patterns below are the literal Go errors you see; pattern-match the prefix to find the right fix.

Error prefixRoot causeFix
dial tcp ... no such hostDNS not resolvingCheck /etc/hosts, VPN, or use IP
dial tcp ...: connect: connection refusedServer pod down or port-forward gonekubectl get pods -n argocd, restart port-forward
x509: certificate signed by unknown authoritySelf-signed TLS--insecure for lab, install CA for production
Failed to invoke grpc call. Use flag --grpc-webIngress (ALB, Nginx) breaks HTTP/2 to backendargocd login --grpc-web persists the flag
rpc error: code = UnauthenticatedToken expiredargocd relogin
rpc error: code = PermissionDenied desc = permission deniedRBAC policy denies the verbargocd account get-user-info, then argocd admin settings rbac can
app is not permitted in projectAppProject whitelist mismatchargocd proj get NAME, then add-source or add-destination
error: ImmutableFieldErrorSpec field that K8s refuses to mutate (e.g. selector)argocd app sync --force
OutOfSync but UI shows matchDefault fields managed by other controllers (HPA replicas)Add ignoreDifferences to the Application spec, or argocd app get --hard-refresh
pod logs forbidden3.0+ enforces logs RBAC by defaultAdd an explicit logs, get, * policy in argocd-rbac-cm

Two structural changes since the early 2.x cheat sheets are worth flagging. ArgoCD 3.0 made logs RBAC enforced by default, so users who could read logs in 2.x suddenly cannot in 3.0 unless you grant the new policy. ArgoCD 3.1 added OCI registries as a first-class source type for Helm charts, which means commands like argocd app create --repo oci://... work without bypass tooling. Both changes are documented in the upstream release notes and worth scanning before upgrades.

A working session: end-to-end recipe

Pulling the pieces together, here is a clean session that takes a fresh ArgoCD install through first login, an app create-sync-rollback cycle, and a token issued for CI. Use this as a smoke test against any cluster:

export ARGOCD_SERVER=argocd.lab.local
export APP=guestbook

# 1. Log in
PASS=$(kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath='{.data.password}' | base64 -d)
argocd login ${ARGOCD_SERVER} --username admin \
  --password "${PASS}" --insecure --grpc-web

# 2. Confirm versions match
argocd version

# 3. Create and sync an app
argocd app create ${APP} \
  --repo https://github.com/argoproj/argocd-example-apps.git \
  --path guestbook \
  --dest-namespace default \
  --dest-server https://kubernetes.default.svc
argocd app sync ${APP}
argocd app wait ${APP} --health --timeout 300

# 4. Verify
argocd app list
argocd app get ${APP} -o tree

# 5. Rollback drill (no-op when there is one revision)
argocd app history ${APP}
argocd app rollback ${APP} 0

# 6. Issue a CI token (account must already have apiKey capability)
argocd account generate-token \
  --account ci-bot \
  --expires-in 30d \
  --id "ci-$(date +%Y-%m)"

This is enough to validate any new ArgoCD install. The same six steps work against EKS, GKE, on-prem K3s, and OpenShift. For platform-specific install paths, the Install ArgoCD on Kubernetes guide covers the upstream manifest path, the ArgoCD on EKS guide handles AWS specifics including IAM and gRPC-Web on ALB, and the ArgoCD on GKE guide covers the GCP path. For Ubuntu-native installs, the Install ArgoCD on Ubuntu 26.04 LTS guide walks through the local cluster setup.

Where to go from here

This guide covers the breadth of the CLI surface; depth lives in dedicated articles in this series. The argocd app sync command alone has thirty-plus flags, five hook types (PreSync, Sync, PostSync, SyncFail, and the new PreDelete added in 3.3), and a sync-wave system that turns ordered manifest application into a first-class concept. Authentication has four modes; the SSO and JWT flows have their own gotchas around group claims and token rotation. The argocd admin family has its own walkthrough including a tested disaster recovery drill. Troubleshooting beyond the quick-lookup table covers gRPC-Web routing through ALB and Nginx, RBAC simulations, and server-log correlation. CI/CD automation with GitHub Actions, GitLab CI, and Jenkins each have their own integration patterns.

For ApplicationSets in production, the ArgoCD ApplicationSet multi-cluster guide walks through Git, Cluster, and Matrix generators against real clusters, including sync waves for ordered rollout and notification hooks for drift alerts. If you are weighing ArgoCD against the alternative GitOps controller, the Flux CD vs ArgoCD comparison covers operator-centric vs API-centric flows, RBAC differences, and Helm integration on both sides. Forgot the admin password during testing? The ArgoCD admin password reset guide covers every reset path.

Bookmark this page as your CLI reference. Pair it with the official command documentation at argo-cd.readthedocs.io for flag-level details and the argoproj/argo-cd releases page to track which 3.x patch your team is on. Keep the CLI close, automate the boring parts, and let ArgoCD do the rest.

Related Articles

Docker Install Docker Registry on Ubuntu 24.04|22.04|20.04 Containers RKE2 High Availability: 3-Node Production Cluster on Rocky Linux 10 Containers Install K3s on Ubuntu 26.04 LTS Automation Migrate from Earthly to Dagger: Complete Guide

Leave a Comment

Press ESC to close