Setting the file. One moment.
Chapter 04 · Cloudflare Deploy
Subchapter 4.159
references/r2-data-catalog/configuration.mdMarkdown5 KBView on GitHub
How to enable R2 Data Catalog and configure authentication.
Choose one method:
npx wrangler r2 bucket catalog enable <BUCKET_NAME>Output:
✅ Data Catalog enabled for bucket 'my-bucket'
Catalog URI: https://<account-id>.r2.cloudflarestorage.com/iceberg/my-bucket
Warehouse: my-bucketResult:
https://<account-id>.r2.cloudflarestorage.com/iceberg/<bucket-name><bucket-name> (same as bucket name)curl -X POST \
"https://api.cloudflare.com/client/v4/accounts/<account-id>/r2/buckets/<bucket>/catalog" \
-H "Authorization: Bearer <api-token>" \
-H "Content-Type: application/json"Response:
{
"result": {
"catalog_uri": "https://<account-id>.r2.cloudflarestorage.com/iceberg/<bucket>",
"warehouse": "<bucket>"
},
"success": true
}npx wrangler r2 bucket catalog status <BUCKET_NAME>Output:
Catalog Status: enabled
Catalog URI: https://<account-id>.r2.cloudflarestorage.com/iceberg/my-bucket
Warehouse: my-bucketnpx wrangler r2 bucket catalog disable <BUCKET_NAME>⚠️ Warning: Disabling does NOT delete tables/data. Files remain in bucket. Metadata becomes inaccessible until re-enabled.
R2 Data Catalog requires API token with both R2 Storage + R2 Data Catalog permissions.
Permission groups included:
Workers R2 Data Catalog Write (or Read)Workers R2 Storage Bucket Item Write (or Read)Use Cloudflare API to create tokens programmatically. Required permissions:
Workers R2 Data Catalog Write (or Read)Workers R2 Storage Bucket Item Write (or Read)from pyiceberg.catalog.rest import RestCatalog
catalog = RestCatalog(
name="my_catalog",
warehouse="<bucket-name>", # Same as bucket name
uri="<catalog-uri>", # From enable command
token="<api-token>", # From token creation
)Full example with credentials:
import os
from pyiceberg.catalog.rest import RestCatalog
# Store credentials in environment variables
WAREHOUSE = os.getenv("R2_WAREHOUSE") # e.g., "my-bucket"
CATALOG_URI = os.getenv("R2_CATALOG_URI") # e.g., "https://abc123.r2.cloudflarestorage.com/iceberg/my-bucket"
TOKEN = os.getenv("R2_TOKEN") # API token
catalog = RestCatalog(
name="r2_catalog",
warehouse=WAREHOUSE,
uri=CATALOG_URI,
token=TOKEN,
)
# Test connection
print(catalog.list_namespaces())See patterns.md for integration examples with other query engines.
For quick reference:
Catalog URI: https://<account-id>.r2.cloudflarestorage.com/iceberg/<bucket>
Warehouse: <bucket-name>
Token: <r2-api-token>Where to find values:
| Value | Source |
|---|---|
<account-id> | Dashboard URL or wrangler whoami |
<bucket> | R2 bucket name |
| Catalog URI | Output from wrangler r2 bucket catalog enable |
| Token | R2 API Token creation page |
# .env (never commit)
R2_CATALOG_URI=https://<account-id>.r2.cloudflarestorage.com/iceberg/<bucket>
R2_WAREHOUSE=<bucket-name>
R2_TOKEN=<api-token>import os
from pyiceberg.catalog.rest import RestCatalog
catalog = RestCatalog(
name="r2",
uri=os.getenv("R2_CATALOG_URI"),
warehouse=os.getenv("R2_WAREHOUSE"),
token=os.getenv("R2_TOKEN"),
)| Problem | Solution |
|---|---|
| 404 “catalog not found” | Run wrangler r2 bucket catalog enable <bucket> |
| 401 “unauthorized” | Check token has both Catalog + Storage permissions |
| 403 on data files | Token needs both permission groups |
See gotchas.md for detailed troubleshooting.