CLI
Run go build ./cmd/iceberg from the root of this repository to build the CLI executable, alternately you can run go install github.com/apache/iceberg-go/cmd/iceberg to install it to the bin directory of your GOPATH.
The iceberg CLI usage is very similar to pyiceberg CLI.
You can pass the catalog URI with the --uri argument.
Connecting to a catalog
Start a local REST catalog (the default --catalog type):
docker pull apache/iceberg-rest-fixture:latest
docker run -p 8181:8181 apache/iceberg-rest-fixture:latest
and run the iceberg CLI pointing to the REST API server:
./iceberg --uri http://0.0.0.0:8181 list
┌─────┐
| IDs |
| --- |
└─────┘
Catalog connection flags are global and apply to every subcommand:
| Flag | Description |
|---|---|
--catalog | Catalog type: rest (default), glue, hive, hadoop, sql. dynamodb is recognized but not implemented yet. |
--uri | Catalog URI (REST/Hive) or SQL DSN |
--warehouse | Warehouse location |
--credential | Credentials for the catalog |
--token | OAuth token (skips OAuth flow) |
--scope | OAuth scope (default catalog) |
--catalog-name | Catalog name to load from config file (default default) |
--config | Path to a config file |
--aws-profile | AWS named profile to use (Glue catalog); overrides aws-profile in the config file |
--sql-driver | database/sql driver name for the SQL catalog. The default CLI binary only compiles in sqliteshim; other drivers require a custom build. |
--sql-dialect | SQL dialect for the SQL catalog. The SQL catalog library supports postgres, mysql, sqlite, mssql, and oracle, but the default CLI binary only ships the sqlite dialect via sqliteshim. Other dialects need a custom build that blank-imports their database/sql drivers. |
To avoid passing flags every time, define a config file at ~/.iceberg-go.yaml:
default-catalog: default
catalog:
default:
type: rest
uri: http://localhost:8181
warehouse: s3://my-warehouse
SQL catalog example:
catalog:
local:
type: sql
uri: file:iceberg-catalog.db
warehouse: file:///tmp/warehouse
sql-driver: sqliteshim
sql-dialect: sqlite
Flags on the command line override values from the config file.
Output format
All commands accept --output text (default, human-readable) or --output json (machine-readable, suitable for piping into jq or scripts).
Catalog and namespace commands
Create namespace
./iceberg --uri http://0.0.0.0:8181 create namespace taxitrips
List namespaces
./iceberg --uri http://0.0.0.0:8181 list
┌───────────┐
| IDs |
| --------- |
| taxitrips |
└───────────┘
Create table
Note: only the identity transform is supported for --partition-spec at this moment.
# Create a simple table with REST catalog and object store
./iceberg create table default.table-1 \
--properties write.format.default=parquet \
--partition-spec foo \
--sort-order foo:desc:nulls-last \
--schema '[{"id":1,"name":"foo","type":"string","required":false},{"id":2,"name":"bar","type":"int","required":true}]' \
--catalog rest \
--uri http://localhost:8181
Table default.table-1 created successfully
# Describe the newly created table
./iceberg describe --catalog rest --uri http://localhost:8181 default.table-1
Table format version | 2
Metadata location | s3://warehouse/default/table-1/metadata/00000-f0ccaadd-d988-482e-99da-3a37870288fe.metadata.json
Table UUID | 33fa3fac-e638-4335-a085-343c6d9e7de5
Last updated | 1753133512562
Sort Order | 1: [
| 1 desc nulls-last
| ]
Partition Spec | [
| 1000: foo: identity(1)
| ]
Current Schema, id=0
├──1: foo: optional string
└──2: bar: required int
Current Snapshot |
Snapshots
Properties
key | value
-----------------------------------------
write.format.default | parquet
write.parquet.compression-codec | zstd
Inspecting tables
info — single-screen summary
iceberg info my_db.events
Reports format version, location, current snapshot, schema, partition spec, sort order, snapshot count, ref count, and property count for a table.
snapshots — snapshot history
iceberg snapshots my_db.events
Lists all snapshots with timestamp, parent snapshot, operation (append, overwrite, delete, replace), and added/deleted data file counts.
refs — branches and tags
iceberg refs my_db.events
iceberg refs --type branch my_db.events
iceberg refs --type tag my_db.events
Lists snapshot refs along with their retention settings (max-ref-age, max-snapshot-age, min-snapshots-to-keep).
partition-stats — partition statistics files
iceberg partition-stats my_db.events # current snapshot
iceberg partition-stats --snapshot-id 7234981023498 my_db.events
iceberg partition-stats --all my_db.events # all snapshots
schema --show-defaults
iceberg schema --show-defaults my_db.events
Prints the schema and surfaces each field's initial-default and write-default — useful when debugging schema-evolution behavior.
Snapshot maintenance
expire-snapshots
Drop old snapshots so their unreferenced data files become eligible for cleanup.
| Flag | Description |
|---|---|
--older-than DURATION | Expire snapshots older than the given duration (7d, 168h) |
--retain-last N | Always keep at least N snapshots, regardless of age |
--dry-run | List what would be expired without committing |
--yes | Skip the confirmation prompt |
# Preview
iceberg expire-snapshots --older-than 7d --dry-run my_db.events
# Commit, retaining at least 5 snapshots
iceberg expire-snapshots --older-than 7d --retain-last 5 my_db.events
clean-orphan-files
Remove data files in the table location that are not referenced by any snapshot's manifests (e.g. left behind by failed writes).
| Flag | Description |
|---|---|
--older-than DURATION | Only consider files older than this (default 72h, gives in-flight writes time to finish) |
--location PATH | Scan a different directory (e.g. an old warehouse path after migration) |
--dry-run | List orphan files without deleting |
--yes | Skip the confirmation prompt |
iceberg clean-orphan-files --dry-run my_db.events
iceberg clean-orphan-files --older-than 5d my_db.events
iceberg clean-orphan-files --location s3://old-warehouse/my_db/events my_db.events
Rollback
Reset the current snapshot pointer to a previous snapshot. The target must be an ancestor of the current snapshot.
| Flag | Description |
|---|---|
--snapshot-id ID | Snapshot to roll back to (required) |
--yes | Skip the confirmation prompt |
iceberg rollback --snapshot-id 6891234567890 my_db.events
Format upgrade
Upgrade the table format version (metadata-only operation; no data files are rewritten). Refuses downgrades and same-version "upgrades".
| Flag | Description |
|---|---|
--dry-run | Show what would change without committing |
--yes | Skip the confirmation prompt |
iceberg upgrade --dry-run my_db.events 2
iceberg upgrade my_db.events 2
Branches and tags
branch create
iceberg branch create my_db.events ml-experiment-v3
| Flag | Description |
|---|---|
--snapshot-id ID | Snapshot the branch points at (default: current snapshot) |
--max-ref-age DURATION | Branch itself expires after this age |
--max-snapshot-age DURATION | Snapshots on the branch older than this can be expired |
--min-snapshots-to-keep N | Always retain at least N snapshots on the branch |
--yes | Skip the confirmation prompt |
iceberg branch create \
--snapshot-id 7234981023498 \
--max-ref-age 30d \
--max-snapshot-age 7d \
--min-snapshots-to-keep 10 \
my_db.events audit-2026-q2
tag create
iceberg tag create my_db.events pre-migration-v4
| Flag | Description |
|---|---|
--snapshot-id ID | Snapshot the tag points at (default: current snapshot) |
--max-ref-age DURATION | Tag is auto-cleaned after this age |
--yes | Skip the confirmation prompt |
iceberg tag create \
--snapshot-id 7234981023498 \
--max-ref-age 90d \
my_db.events monthly-backup-may
Automation
Two flags make these commands safe to run from cron jobs or CI:
--yesskips the interactive prompt. Without it in a non-interactive environment, the CLI exits withstdin is not a terminal: use --yes to confirm in non-interactive moderather than hanging.--output jsonemits structured output that can be consumed byjqand downstream tooling.
Daily maintenance over every table in a namespace:
#!/bin/bash
TABLES=$(iceberg list my_db --output json | jq -r '.identifiers[].name')
for table in $TABLES; do
iceberg expire-snapshots --older-than 7d --retain-last 3 --yes \
--output json "my_db.$table"
iceberg clean-orphan-files --older-than 3d --yes \
--output json "my_db.$table"
done
Tag tables before a deploy:
iceberg tag create --yes my_db.events "pre-deploy-$VERSION"
iceberg tag create --yes my_db.users "pre-deploy-$VERSION"
Audit-only report (no commits):
iceberg expire-snapshots --older-than 7d --dry-run --output json my_db.events \
| jq '{table, would_expire: .expired_snapshot_count}'
Safety features
Every write command has multiple layers of protection:
--dry-run— shows the would-be effect without committing. Look for[DRY RUN]in text output or"dry_run": truein JSON.--yes— required to skip the prompt; without it, non-interactive shells get an explicit error rather than hanging.- TTY detection — interactive prompts are only shown when stdout is a terminal.
- Ancestor validation —
rollbackrejects target snapshots that are not in the current branch's history. - Version check —
upgraderefuses same-version or downgrade requests.