Skip to content

Querying a DuckDB Iceberg Catalog

How to query an Iceberg REST catalog from the DuckDB CLI, backed by a local MinIO (S3) store and a Polaris catalog server.

DuckDB reads Iceberg tables through its iceberg extension, authenticating to the catalog over the Iceberg REST protocol and reading the underlying data files from S3-compatible storage. This guide connects to a local development stack; for the full extension reference, see the DuckDB Iceberg documentation.

Prerequisites

  • DuckDB installed and on your PATH (duckdb --version to confirm).
  • A MinIO (or other S3-compatible) store running locally on localhost:9000, holding the table data.
  • A Polaris (Iceberg REST) catalog server running locally on localhost:8181.
  • Credentials for both: an S3 key/secret for MinIO and an OAuth2 client ID/secret for the catalog. The values below are the local development defaults — replace them with your own and never reuse them outside a local stack.

Steps

1. Start the DuckDB shell

duckdb

All remaining commands are SQL run inside this shell.

2. Install the extensions

iceberg reads the table format, httpfs fetches data over S3/HTTP, and aws resolves S3-style credentials. Installing is a one-time operation — DuckDB persists installed extensions across sessions.

INSTALL iceberg;
INSTALL httpfs;
INSTALL aws;

3. Load the extensions

Loading must be done once per session.

LOAD iceberg;
LOAD httpfs;
LOAD aws;

4. Create the secrets

Two secrets are required: one authorizes S3 data access to MinIO, and the other handles OAuth2 authentication against the Polaris catalog. Creating both up front lets the later ATTACH reference the catalog secret by name.

-- S3 data access to the MinIO store.
CREATE OR REPLACE SECRET testProj_iceberg_s3 (
  TYPE s3,
  KEY_ID 'admin',
  SECRET 'admin123',
  REGION 'us-east-1',
  ENDPOINT 'localhost:9000',
  USE_SSL false,
  URL_STYLE 'path'
);

-- Catalog auth (OAuth2 against Polaris).
CREATE OR REPLACE SECRET testProj_iceberg_rest (
  TYPE iceberg,
  CLIENT_ID 'dev-client_id',
  CLIENT_SECRET 'dev-client-secret',
  OAUTH2_SERVER_URI 'http://localhost:8181/api/catalog/v1/oauth/tokens',
  OAUTH2_SCOPE 'PRINCIPAL_ROLE:ALL'
);

5. Attach the catalog

Point DuckDB at the catalog's REST endpoint and authenticate with the secret from step 4. The attached catalog is then addressable as gdd_iceberg_catalog.

ATTACH 'gdd-iceberg-catalog-dev' AS gdd_iceberg_catalog (
  TYPE iceberg,
  ENDPOINT 'http://localhost:8181/api/catalog',
  SECRET testProj_iceberg_rest
);

6. Verify the connection

List every table the catalog exposes. If the attach succeeded and the backing services are running, the catalog's tables appear here — you can then query any of them with standard SQL.

SHOW ALL TABLES;

See Also