You're paged about a failed job or a cluster that has been running all weekend, and the UI is slow or you need the same action across twenty objects. The Databricks CLI does it from a terminal and returns JSON you can script against. This page groups the commands by task.
Note
This is the current CLI (version 0.205 and later). The old
databricks-clipip package uses different syntax, such asdatabricks runs list. Rundatabricks --versionfirst. If it prints0.18or lower, you have the legacy CLI.
Install and sign in
# Windows
winget install Databricks.DatabricksCLI
# macOS / Linux
brew tap databricks/tap && brew install databricks
databricks --version
Sign in with OAuth (user-to-machine). This creates or updates a profile in ~/.databrickscfg (on Windows, %USERPROFILE%\.databrickscfg):
databricks auth login --host https://adb-1234567890123456.7.azuredatabricks.net --profile prod
databricks auth profiles # lists profiles and checks each one is valid
databricks auth describe -p prod # shows which credential and source are used
databricks current-user me -p prod # confirms who you are in the workspace
For automation, use a service principal instead of a personal token. With an Entra ID service principal, the CLI reads the standard environment variables:
export DATABRICKS_HOST=https://adb-1234567890123456.7.azuredatabricks.net
export ARM_TENANT_ID=<tenant-guid>
export ARM_CLIENT_ID=<app-id>
export ARM_CLIENT_SECRET=<secret> # or use a managed identity / workload identity federation
databricks current-user me
If you're already signed in with az login, you can add auth_type = azure-cli to a profile and the CLI will use your Azure CLI token.
Flags you'll use on every command
| Flag | What it does |
|---|---|
-p, --profile prod | Pick the workspace profile. Without it the CLI uses DEFAULT |
-o json | JSON output for jq or ConvertFrom-Json |
--debug | Shows the HTTP requests. Use it on 401/403 errors to see which host and auth type were used |
--no-wait | Returns straight away instead of waiting for a cluster or run to finish |
--json @file.json | Sends a full request body from a file |
Tip
Put
-p prodin every command you run against production, even whenDEFAULTalready points there. The day someone changesDEFAULT, you won't terminate clusters in the wrong workspace.
Clusters
# Running clusters only, with who/what started them
databricks clusters list --cluster-states RUNNING -p prod -o json \
| jq -r '.[] | [.cluster_id, .cluster_name, .cluster_source, .creator_user_name] | @tsv'
# Full config of one cluster (runtime, node types, policy, access mode)
databricks clusters get 0926-101530-abcd1234 -p prod -o json \
| jq '{spark_version, node_type_id, num_workers, autoscale, data_security_mode, policy_id, state, termination_reason}'
# Last 20 events: resize, termination reasons, init script failures
databricks clusters events 0926-101530-abcd1234 --order DESC --page-size 20 -p prod -o json \
| jq -r '.[] | [.timestamp, .type, (.details.reason.code // "")] | @tsv'
# Start, restart, terminate
databricks clusters start 0926-101530-abcd1234 -p prod --no-wait
databricks clusters restart 0926-101530-abcd1234 -p prod
databricks clusters delete 0926-101530-abcd1234 -p prod # terminates; config is kept
Warning
clusters deleteonly terminates the cluster.clusters permanent-deleteremoves it and its configuration, and you can't undo it. Don't usepermanent-deletein a cleanup script unless you've exported the cluster JSON first.
Terminate every running all-purpose cluster created through the UI (for example, after hours in a dev workspace):
databricks clusters list --cluster-states RUNNING --cluster-sources UI -p dev -o json \
| jq -r '.[].cluster_id' \
| xargs -I{} databricks clusters delete {} -p dev --no-wait
Other useful lookups:
databricks clusters spark-versions -p prod -o json | jq -r '.versions[] | select(.name | test("LTS")) | .key'
databricks clusters list-node-types -p prod -o json | jq -r '.node_types[].node_type_id' | grep -i E8
databricks clusters get-permissions 0926-101530-abcd1234 -p prod
Jobs and runs
| Task | Command |
|---|---|
| Find a job by name | databricks jobs list --name "nightly_sales_load" -p prod |
| Show job settings | databricks jobs get <job-id> -p prod -o json |
| Active runs of one job | databricks jobs list-runs --job-id <job-id> --active-only -p prod |
| Last 10 runs | databricks jobs list-runs --job-id <job-id> --limit 10 -p prod |
| Run details incl. repairs | databricks jobs get-run <run-id> --include-history -p prod |
| Task output / error | databricks jobs get-run-output <task-run-id> -p prod |
| Trigger now, don't wait | databricks jobs run-now <job-id> --no-wait -p prod |
| Cancel one run | databricks jobs cancel-run <run-id> -p prod |
| Cancel all runs of a job | databricks jobs cancel-all-runs --job-id <job-id> -p prod |
| Rerun only failed tasks | databricks jobs repair-run <run-id> --rerun-all-failed-tasks -p prod |
get-run-output takes a task run ID, not the parent job run ID. For a multi-task job, get the task run IDs first:
databricks jobs get-run 556677 -p prod -o json \
| jq -r '.tasks[] | [.task_key, .run_id, .state.result_state, (.state.state_message // "")] | @tsv'
databricks jobs get-run-output 556690 -p prod -o json | jq -r '.error, .error_trace' | head -40
Trigger a run with job parameters:
databricks jobs run-now 123456 -p prod --no-wait \
--json '{"job_id": 123456, "job_parameters": {"load_date": "2026-10-25"}}'
Caution
repair-run --rerun-dependent-tasksalso reruns downstream tasks that succeeded. If those tasks append data without a MERGE or overwrite, you'll get duplicates. Check what each dependent task writes before you add the flag.
Pause a schedule during an incident (it's a partial update, so other settings stay as they are):
databricks jobs update 123456 -p prod \
--json '{"new_settings": {"schedule": {"quartz_cron_expression": "0 0 2 * * ?", "timezone_id": "UTC", "pause_status": "PAUSED"}}}'
The schedule block is replaced as a whole, so copy the current cron and time zone from jobs get first.
Notebooks, workspace files and volumes
# List and back up a folder before you change it
databricks workspace list /Workspace/Shared/etl -p prod
databricks workspace export-dir /Workspace/Shared/etl ./backup/etl -p prod
# One notebook as source code
databricks workspace export /Workspace/Shared/etl/load_sales --format SOURCE --file load_sales.py -p prod
# Push a hotfix (overwrites the existing notebook)
databricks workspace import /Workspace/Shared/etl/load_sales --file load_sales.py \
--format SOURCE --language PYTHON --overwrite -p prod
Unity Catalog volumes are reached through databricks fs with a dbfs:/Volumes/... path:
databricks fs ls dbfs:/Volumes/main/raw/landing/ -p prod
databricks fs cp ./sample.csv dbfs:/Volumes/main/raw/landing/sample.csv --overwrite -p prod
databricks fs cp -r dbfs:/Volumes/main/raw/landing/2026-10-25/ ./landing-copy/ -p prod
Tip
For production code, deploy with Databricks Asset Bundles (
databricks bundle deploy -t prod) rather thanworkspace import. Useimportfor emergency hotfixes only, and commit the same change to Git afterwards so the next deploy doesn't overwrite it.
SQL warehouses
databricks warehouses list -p prod -o json | jq -r '.[] | [.id, .name, .state, .cluster_size] | @tsv'
databricks warehouses start <warehouse-id> -p prod
databricks warehouses stop <warehouse-id> -p prod
Unity Catalog: objects and grants
databricks catalogs list -p prod
databricks schemas list main -p prod
databricks tables list main sales -p prod -o json | jq -r '.[].full_name'
# Direct grants on an object
databricks grants get table main.sales.orders -p prod
# Effective grants, including those inherited from schema and catalog
databricks grants get-effective table main.sales.orders --principal analysts -p prod
get-effective answers "why can (or can't) this group read the table?" without stepping through the catalog and schema yourself. Grant changes take a JSON body:
databricks grants update schema main.sales -p prod \
--json '{"changes": [{"principal": "analysts", "add": ["USE_SCHEMA", "SELECT"]}]}'
When the CLI doesn't have a command
databricks api calls any REST endpoint with the same profile and authentication:
databricks api get /api/2.0/clusters/list -p prod
databricks api post /api/2.0/clusters/delete --json '{"cluster_id": "0926-101530-abcd1234"}' -p prod
Common errors
| Error | Cause | Fix |
|---|---|---|
cannot configure default credentials | No profile, or the profile has no host | databricks auth login --host ... --profile ..., or pass -p |
401 Unauthorized / invalid access token | Expired OAuth session or revoked token | databricks auth login -p prod again. For service principals, check the secret's expiry date |
403 ... does not have ... permission | Identity lacks the workspace or object permission | clusters get-permissions / jobs get-permissions; check group membership |
unknown command "runs" | Legacy CLI syntax | Use databricks jobs list-runs / get-run |
| JSON quoting fails in PowerShell | PowerShell strips the inner quotes | Put the body in a file and pass --json @body.json |
RESOURCE_DOES_NOT_EXIST on a workspace path | Path is missing the /Workspace prefix or is a Git folder path | Run databricks workspace list on the parent folder |
Prevent it next time
- Give each workspace a named profile (
dev,test,prod). Don't put production inDEFAULT. - Run automation as a service principal with OAuth, not as a person with a personal access token.
- Keep the scripts you use often (stop idle clusters, rerun failed tasks) in a Git repo and run them from CI or a runbook, so nobody has to retype them during an incident.
- Pin a CLI version in CI (
databricks --versionin the pipeline log). Command flags change between releases. Rundatabricks <group> <command> --helpon your build to check them.