Kenneth Oh
07/28/2026, 4:48 AMRocky
07/28/2026, 4:48 AMFailed to load rest catalog during Iceberg catalog creation usually indicates that the StarRocks Frontend (FE) cannot reach or authenticate with your Iceberg REST server.
Since you are running StarRocks in a Docker container on a Mac (Apple Silicon), this is likely a networking or configuration issue. Here are the most common causes and fixes:
1. Networking: Use host.docker.internal
If your Iceberg REST catalog (e.g., Polaris, Tabular, or a local REST fixture) is running on your Mac host (outside the StarRocks container) and you are using localhost or 127.0.0.1 in the iceberg.catalog.uri, the connection will fail. Inside the container, localhost refers to the container itself.
* Fix: Replace localhost with host.docker.internal.
sql
CREATE EXTERNAL CATALOG iceberg
PROPERTIES (
"type" = "iceberg",
"iceberg.catalog.type" = "rest",
"iceberg.catalog.uri" = "<http://host.docker.internal:8181>", -- Correct for Mac Docker
"iceberg.catalog.warehouse" = "your_warehouse_name"
);
2. Mandatory Properties
For a REST catalog, StarRocks requires specific properties. If you are missing any, the initialization will fail. Ensure you have:
* "iceberg.catalog.type" = "rest"
* "iceberg.catalog.uri" (The API endpoint)
* "iceberg.catalog.warehouse" (The warehouse identifier)
3. OAuth2 Configuration (If applicable)
If your REST catalog requires authentication (like Apache Polaris), ensure your credentials are correct. There is a known issue in some versions where the scope parameter might be required.
sql
"iceberg.catalog.security" = "oauth2",
"iceberg.catalog.oauth2.credential" = "client_id:client_secret",
"iceberg.catalog.oauth2.scope" = "PRINCIPAL_ROLE:ALL" -- Often required for Polaris
4. Apple Silicon (ARM64) Image Compatibility
Ensure you are using an official StarRocks image that supports ARM64. The starrocks/all-in-one:latest image generally supports ARM64, but if you are using an older version, the Java Native Interface (JNI) calls required for certain external connectors might fail.
* Recommendation: Use the starrocks/all-in-one:latest or starrocks/fe-ubuntu:latest images which are regularly tested on Apple Silicon.
5. Check Logs for Details
The error message in the SQL client is a summary. To see the underlying Java exception (e.g., Connection Refused or 401 Unauthorized), check the FE logs:
bash
docker exec -it quickstart tail -f /opt/starrocks/fe/log/fe.warn.log
Look for a stack trace starting with com.starrocks.connector.iceberg.rest.IcebergRESTCatalog.
If you are trying to test Iceberg locally, it is highly recommended to use the StarRocks Iceberg Docker Compose instead of the "shared-nothing" (all-in-one) tutorial, as it sets up a pre-configured network with a REST catalog and MinIO for you.
References
• developers/mac-compile-run-test.md
• quick_start/shared-nothing.md
• quick_start/iceberg.mdKenneth Oh
07/28/2026, 4:50 AMCREATE EXTERNAL CATALOG `iceberg`
PROPERTIES (
"aws.s3.access_key" = "**",
"aws.s3.secret_key" = "**",
"iceberg.catalog.rest.access-key-id" = "**",
"iceberg.catalog.uri" = "<https://s3tables.us-east-1.amazonaws.com/iceberg>",
"type" = "iceberg",
"aws.s3.use_aws_sdk_default_behavior" = "false",
"iceberg.catalog.rest.secret-access-key" = "**",
"aws.s3.region" = "us-east-1",
"aws.s3.use_instance_profile" = "false",
"iceberg.catalog.rest.sigv4-enabled" = "true",
"iceberg.catalog.warehouse" = "arn:aws:s3tables:us-east-1:**:bucket/**",
"iceberg.catalog.rest.signing-name" = "s3tables",
"iceberg.catalog.type" = "rest"
)Rocky
07/28/2026, 4:51 AMFailed to load rest catalog occurs when the StarRocks Frontend (FE) cannot successfully perform the initial handshake (usually a GET /v1/config call) with the Iceberg REST endpoint.
Since this works on EKS but fails in your local Docker environment on Mac, the issue is likely related to network connectivity, SSL/Trust stores, or the Docker image version.
1. Match the Official S3 Tables Configuration
While AWS S3 Tables has its own endpoint, the StarRocks documentation specifically recommends accessing S3 Tables through the AWS Glue Iceberg REST endpoint. There are slight differences in the signing name and URI. Try updating your catalog statement to match the official guide:
* URI: <https://glue>.<region>.<http://amazonaws.com/iceberg|amazonaws.com/iceberg>
* Signing Name: glue
sql
CREATE EXTERNAL CATALOG iceberg
PROPERTIES (
"type" = "iceberg",
"iceberg.catalog.type" = "rest",
"iceberg.catalog.uri" = "<https://glue.us-east-1.amazonaws.com/iceberg>", -- Change to Glue endpoint
"iceberg.catalog.rest.sigv4-enabled" = "true",
"iceberg.catalog.rest.signing-name" = "glue", -- Change to glue
"iceberg.catalog.rest.access-key-id" = "YOUR_ACCESS_KEY",
"iceberg.catalog.rest.secret-access-key" = "YOUR_SECRET_KEY",
"iceberg.catalog.warehouse" = "YOUR_ACCOUNT_ID:s3tablescatalog/YOUR_TABLE_BUCKET",
"aws.s3.region" = "us-east-1"
);
2. Check for SSL/Certificate Issues
Local Docker images (especially older all-in-one builds) sometimes lack the updated CA certificates required to verify the SSL for newer AWS endpoints like s3tables.
* Test: Check if the container can reach the endpoint using curl from inside the container:
bash
docker exec -it <container_id> curl -v <https://s3tables.us-east-1.amazonaws.com/iceberg/v1/config>
* If you see an SSL certificate error, you may need to update the CA certificates inside the container or provide a custom trust store.
3. Verify Docker Image Version
Support for iceberg.catalog.rest.sigv4-enabled and S3 Tables was added in StarRocks v3.3.6+ and v3.4.1+.
* The starrocks/all-in-one:latest image on Docker Hub is often a specific version (like 3.2.x or 3.3.x). If your local image is cached and older than the version running on EKS, it won't recognize the SigV4 properties.
* Fix: Run docker pull starrocks/all-in-one:latest to ensure you have the most recent version, or explicitly use starrocks/all-in-one:3.4.2 (or higher).
4. Debugging via FE Logs
The SQL error is a summary. The actual Java exception (e.g., UnknownHostException, SSLHandshakeException, or 403 Forbidden) is logged in the FE.
Run this to see the detailed stack trace:
bash
docker exec -it <container_id> tail -f /opt/starrocks/fe/log/fe.warn.log
Look for lines starting with Failed to load rest catalog. If it says "Unknown Property", your StarRocks version is too old. If it says "Connection Refused", it is a networking/proxy issue.
5. IAM Permissions (Local vs EKS)
On EKS, your cluster might have an IAM Role (IRSA) that grants s3tables:_ and glue:_ permissions. Locally, you are using Access Keys. Ensure that the specific IAM User associated with those keys has:
1. S3 Tables permissions (s3tables:GetTable, etc.)
2. Glue permissions (glue:GetDatabase, etc.)
3. Lake Formation permissions (if applicable, as S3 Tables requires Lake Formation "Allow external engines" setting).
References
• data_source/catalog/iceberg/iceberg_rest_s3.md
• data_source/catalog/iceberg/iceberg_catalog.md
• quick_start/shared-nothing.md
)
References
• data_source/catalog/iceberg/iceberg_rest_s3.mdRocky
07/28/2026, 4:51 AMKenneth Oh
07/28/2026, 7:57 AMRocky
07/28/2026, 7:57 AMORDER BY):
When creating the MV, use the ORDER BY clause to ensure the column you are querying by is the first column in the sort key. This enables the Prefix Index.
sql
CREATE MATERIALIZED VIEW iceberg_mv
ORDER BY (your_id_column) -- This is critical for point queries
DISTRIBUTED BY HASH(your_id_column)
AS SELECT ... FROM iceberg_catalog.db.table;
* Add Secondary Indexes:
Just like a regular table, you can add Bloom Filter or Bitmap indexes to an MV after it is created to accelerate specific filters.
sql
-- Add Bloom Filter for the ID column
ALTER MATERIALIZED VIEW iceberg_mv SET ("bloom_filter_columns" = "your_id_column");
* Check Bucketing:
Ensure the BUCKETS count in your MV matches the native table's distribution. Too many buckets for a small point query can add latency due to scheduling overhead.
3. Understanding the 150ms Overhead
The difference between 50ms and 200ms in a "Shared Data" (EKS) environment vs. a "Local BE" is often attributable to:
* Query Rewrite Overhead: When you query the base Iceberg table and let the optimizer "transparently rewrite" it to use the MV, there is a slight planning overhead (usually 10-50ms). Try querying the MV directly (SELECT ... FROM iceberg_mv) to see if the latency drops.
* Metadata Overhead: Shared-data clusters (StarRocks 3.x+) fetch metadata from an object store (S3). Even if the data is cached, the metadata lookup or the "Shared-Data" architecture overhead can account for the extra milliseconds compared to a single local BE node reading from an NVMe SSD.
* Data Cache: Ensure the Data Cache is warm. In a shared-data cluster, the first query fetches data from S3 to the BE's local disk/memory cache. Subsequent queries should be faster.
Summary Checklist
1. Direct Query: Query the MV name directly to bypass rewrite logic.
2. Sort Keys: Ensure ORDER BY is used in the MV creation for your lookup columns.
3. Index: Add a Bloom Filter to the lookup columns.
4. Table Model: If 50ms is a hard requirement for point queries and the MV (Duplicate model) can't reach it, you may need to use a Primary Key table and an INSERT INTO ... SELECT job instead of an MV.
References
• using_starrocks/async_mv/use_cases/data_lake_query_acceleration_with_materialized_views.md
• sql-reference/sql-statements/materialized_view/CREATE_MATERIALIZED_VIEW.mdKenneth Oh
07/28/2026, 7:59 AMRocky
07/28/2026, 7:59 AMsql
CREATE TABLE native_iceberg_sync (
id BIGINT NOT NULL,
data_val VARCHAR(255),
updated_at DATETIME
)
PRIMARY KEY (id)
DISTRIBUTED BY HASH(id)
PROPERTIES (
-- Use cloud-native persistent index for shared-data performance
"enable_persistent_index" = "true",
"persistent_index_type" = "CLOUD_NATIVE"
);
2. Schedule a periodic refresh task:
This task will run an INSERT INTO ... SELECT at your desired interval. Because it is a Primary Key table, it will automatically perform an Upsert (updating existing rows and inserting new ones).
sql
SUBMIT TASK iceberg_refresh_job
SCHEDULE EVERY(INTERVAL 10 MINUTE)
AS
INSERT INTO native_iceberg_sync
SELECT id, data_val, updated_at
FROM iceberg_catalog.your_db.your_table
WHERE updated_at > date_sub(now(), INTERVAL 15 MINUTE); -- Incremental sync example
Option 2: Asynchronous Materialized View (Easiest Management)
An Asynchronous MV is essentially a native StarRocks table that StarRocks manages for you. It is the recommended way to accelerate Iceberg data if you don't specifically need the Primary Key model.
sql
CREATE MATERIALIZED VIEW iceberg_mv
-- Optimizations for performance matching native tables
ORDER BY (id)
DISTRIBUTED BY HASH(id)
REFRESH ASYNC EVERY(INTERVAL 10 MINUTE)
PROPERTIES (
"datacache.enable" = "true"
)
AS
SELECT id, data_val, updated_at
FROM iceberg_catalog.your_db.your_table;
Key Differences for Shared-Data Mode
* Storage Format: Both options store data in StarRocks' internal format on your object storage (S3/EKS).
* Query Performance: The Primary Key table (Option 1) will be faster for point queries (searching by ID) because of its unique index. The MV (Option 2) is better for analytical scans and aggregations.
* Caching: In shared-data mode, ensure datacache.enable is true (it is by default). This ensures that once the data is "refreshed" into the native table, it stays on the local NVMe/SSD of the BE nodes for that 50ms response time.
* Incremental Refresh: MVs on Iceberg can automatically detect partition changes and refresh only the new data. With a manual TASK, you must write the WHERE clause logic yourself to avoid scanning the entire Iceberg table every time.
Recommendation: If you need the 50ms latency you mentioned previously, use Option 1 with a Primary Key table and a scheduled TASK.
References
• sql-reference/sql-statements/loading_unloading/ETL/SUBMIT_TASK.md
• table_design/table_types/primary_key_table.md
• using_starrocks/async_mv/use_cases/data_lake_query_acceleration_with_materialized_views.md
References
• best_practices/primarykey_table.md
• table_design/table_types/primary_key_table.mdKenneth Oh
07/28/2026, 8:05 AMRocky
07/28/2026, 8:05 AM"datacache.enable" = "true" (the default), StarRocks writes data to both S3 and the local disk during ingestion.
* Point Queries: For your 50ms requirement, the query doesn't actually go to S3. The BE/CN checks its local cache. If the data is there, it reads from the local NVMe/SSD at local speeds.
* Persistent Index: For Primary Key tables specifically, StarRocks also maintains a "Persistent Index." In shared-data mode, this index can also be offloaded and cached to ensure fast lookups without needing massive amounts of RAM.
3. Why not store it directly on disk?
If you store data only on the BE disks (the old "Shared Nothing" way), you lose the primary benefits of EKS/Cloud-native deployments:
* Scalability: If a BE node dies or you scale down, you lose the data on that disk. With S3 storage, any new BE node can immediately start serving the same data by pulling from S3 into its local cache.
* Cost: S3 is significantly cheaper for storing terabytes of data than high-performance EKS EBS volumes or local NVMe.
Summary of Performance
The reason your "Local Docker" setup is fast is likely because the disk and compute are on the same machine. In your Shared Data EKS cluster, you get the same 50ms performance as long as the Data Cache is warm.
If you are seeing 200ms on a native table in EKS, check these two things:
1. Warm the Cache: Is the data actually in the cache? Run the query twice; the second time should be much faster.
2. Persistent Index: Ensure you have "enable_persistent_index" = "true" in your table properties so the Primary Key lookups are optimized for the cloud-native architecture.
References
• introduction/Architecture.md
• deployment/shared_data/s3.md
• table_design/table_types/primary_key_table.md
References
• introduction/Architecture.md
• deployment/shared_data/s3.md
• table_design/table_design.md
• deployment/shared_data/feature-support-shared-data.mdKenneth Oh
07/28/2026, 8:07 AMRocky
07/28/2026, 8:08 AMKenneth Oh
07/28/2026, 8:09 AMRocky
07/28/2026, 8:10 AM"store_row_column" = "true") creates a dedicated row-oriented storage alongside the columnar data to accelerate point queries and short-circuit lookups.
* Shared-Nothing (Local Storage): Supported.
* Shared-Data (S3 Storage): Not supported ❌. According to the official compatibility matrix, this is planned for a future release but is currently unavailable in shared-data clusters.
2. Partial Update in "Row Mode"
You might see "Row mode" mentioned in documentation for shared-data clusters. This refers to the Partial Update strategy:
* Row Mode (Supported): When you update a few columns, StarRocks reads the entire row, updates the necessary fields, and writes a completely new version of the row. This is the default and only way shared-data clusters handled partial updates until recently.
* Column Mode (Supported since v3.3.1): Only the updated columns are written, which is more efficient for tables with hundreds of columns.
Impact on your 50ms Goal
Even without the dedicated "Row Store" property, you can still achieve very low latency in shared-data mode by following these steps:
1. Use Primary Key Tables: They use a "Delete+Insert" strategy that is significantly faster for point queries than other models.
2. Persistent Index: Use "enable_persistent_index" = "true" and "persistent_index_type" = "CLOUD_NATIVE". This ensures the primary key index (which maps your ID to the file location) is stored on S3 and cached locally, preventing high memory usage while keeping lookups fast.
3. Data Cache: Ensure your EKS nodes have sufficient NVMe/SSD space for the datacache. Since your queries are likely point queries on "hot" data, the data will be served from the local cache, avoiding S3 latency.
Summary: You cannot use the store_row_column property yet in your EKS shared-data environment, but a standard Primary Key table with a warm Data Cache is usually sufficient to meet sub-100ms requirements.
References
• deployment/shared_data/feature-support-shared-data.md
• table_design/hybrid_table.md
• table_design/table_types/primary_key_table.md
References
• deployment/shared_data/feature-support-shared-data.md
• table_design/table_types/primary_key_table.md
• table_design/hybrid_table.mdKenneth Oh
07/28/2026, 8:11 AMRocky
07/28/2026, 8:11 AM"store_row_column" = "true") is still not supported for shared-data clusters.
According to the latest feature compatibility matrix for StarRocks 4.1:
* Row Store (Hybrid Row-Column): Remains "To be supported" for shared-data mode. This feature is currently only available for shared-nothing (local storage) clusters.
* Persistent Index: This is fully supported and recommended for shared-data mode. In v4.1, you should use "persistent_index_type" = "CLOUD_NATIVE", which stores the index on S3/Object Storage while caching it locally for speed. This provides the fast primary key lookups you need for your 50ms goal.
What’s New in 4.1 for Shared-Data Performance?
While the dedicated row-store property is missing, v4.1 introduces other features that significantly improve performance in cloud-native environments:
1. Inverted Index Support: v4.1 brings support for inverted indexes to shared-data clusters. This allows for ultra-fast text searching and filtering on non-primary-key columns, similar to how the row store helps point lookups.
2. Range-Based Distribution: v4.1 supports range-based data distribution for both shared-nothing and shared-data clusters, which can help prune data more effectively for specific query patterns.
3. Enhanced Cloud-Native Persistent Index: Continued optimizations to the CLOUD_NATIVE index type reduce the memory overhead and improve the speed of finding row locations on S3.
Recommendation for your 50ms Latency
To achieve your latency target in v4.1 without the row store property:
1. Warm the Data Cache: Use the CACHE SELECT or warmup tasks introduced in v3.3+ to ensure your "hot" data is already on the local NVMe of your EKS nodes.
2. Cloud-Native Persistent Index: Ensure your table is created with:
sql
PROPERTIES (
"enable_persistent_index" = "true",
"persistent_index_type" = "CLOUD_NATIVE"
);
3. Point Lookup Optimization: Since the row store is unavailable, ensure your query explicitly filters by the Primary Key to take advantage of the index.
References
• deployment/shared_data/feature-support-shared-data.md
• table_design/table_types/primary_key_table.md
• table_design/hybrid_table.md
References
• deployment/shared_data/feature-support-shared-data.md
• table_design/table_types/primary_key_table.md
• table_design/hybrid_table.md
References
• deployment/shared_data/feature-support-shared-data.md
• knowledge/admin_and_operation/shared_data_compaction.mdKenneth Oh
07/28/2026, 8:12 AMRocky
07/28/2026, 8:12 AMsql
CREATE MATERIALIZED VIEW iceberg_acceleration_mv
DISTRIBUTED BY HASH(id)
REFRESH ASYNC EVERY (INTERVAL 10 MINUTE) -- Or MANUAL
PROPERTIES (
-- Allows the query to be rewritten even if the MV is slightly behind the Iceberg table
-- This is critical for sub-50ms response times.
"mv_rewrite_staleness_second" = "3600",
-- Ensures StarRocks considers this external table for rewrite
"force_external_table_query_rewrite" = "true"
)
AS
SELECT id, name, timestamp FROM iceberg_catalog.db.table;
Important Considerations for Shared-Data Mode
* Staleness: By default, StarRocks checks if the Iceberg table has changed. If it has, it might skip the rewrite to ensure "fresh" data, which puts you back on the slow 200ms path. By setting mv_rewrite_staleness_second, you tell StarRocks: "I'm okay with data that is X seconds old; just give me the 50ms response time."
* Storage: In shared-data mode, the MV data will be stored on S3, but its Persistent Index and Data Cache will live on your EKS worker nodes (BEs).
* Query Pattern: The rewrite works best for "SPJG" queries (Select, Project, Join, Group-by). Simple point lookups by ID are very easy for the optimizer to rewrite.
Summary: This is the most "elegant" solution because your BI tools and users keep querying iceberg_catalog.table, but they get the performance of a native StarRocks table.
References
• using_starrocks/async_mv/use_cases/data_lake_query_acceleration_with_materialized_views.md
• using_starrocks/async_mv/use_cases/query_rewrite_with_materialized_views.md
• sql-reference/sql-statements/materialized_view/CREATE_MATERIALIZED_VIEW.md
References
• using_starrocks/async_mv/use_cases/data_lake_query_acceleration_with_materialized_views.md
• using_starrocks/async_mv/use_cases/query_rewrite_with_materialized_views.md
• sql-reference/sql-statements/materialized_view/CREATE_MATERIALIZED_VIEW.md
ReferencesKenneth Oh
07/28/2026, 8:13 AMRocky
07/28/2026, 8:13 AMiceberg_catalog.db.table and redirects it to an internal table).
Transparent rewrite is a core logic of the MV engine. However, you can achieve a similar result using Logical Views and Catalog Management, provided you can make a small configuration change at the session or application connection level.
The "Catalog Shadowing" Strategy
If you cannot use MVs but want to "redirect" queries to a native StarRocks table in shared-data mode, you can use the following approach:
1. Create a Native Table: Create your StarRocks native table in the default_catalog.
sql
CREATE TABLE default_catalog.my_db.native_iceberg_data (...)
PROPERTIES ("enable_persistent_index" = "true");
2. Create a Logical View: Create a view in the default_catalog that has the exact same name as your Iceberg table.
sql
CREATE VIEW default_catalog.my_db.iceberg_table_name AS
SELECT * FROM default_catalog.my_db.native_iceberg_data;
3. Switch the Session Catalog: Configure your application or BI tool to run SET CATALOG default_catalog; and USE my_db; upon connecting.
How it works:
If the application sends the query SELECT _ FROM iceberg_table_name, StarRocks will look in the _current* catalog and database first. It will find your Logical View (which points to the native table) and execute it, completely bypassing the actual Iceberg catalog.
Why this is different from MVs
* No Fully Qualified Names: This only works if your application does not use fully qualified names (e.g., it must query table_name instead of iceberg_catalog.db.table_name). If the application explicitly prefixes the Iceberg catalog, StarRocks will always go to Iceberg.
* Manual Sync: Unlike an MV, which has a REFRESH property, you are responsible for manually keeping the data in your native table synchronized with the source Iceberg table (e.g., using INSERT INTO ... SELECT).
* No "Staleness" Logic: A Logical View is just a pointer. It doesn't have the sophisticated consistency checks or "staleness" tolerances that MVs provide.
Summary: Can you do it without MVs?
Feature | Asynchronous MV | Logical View + Catalog Switch
Transparent? | Yes (handles iceberg_catalog prefix) | No (requires unqualified names)
Metadata Speed | Fast (Internal) | Fast (Internal)
Data Freshness | Automatic (Refresh) | Manual (Insert into)
Rewrite Logic | Built-in Optimizer | Name Matching
Recommendation: If you are trying to avoid MVs because of the "background refresh" overhead, consider using an MV with REFRESH MANUAL. This gives you the Transparent Rewrite (so you don't have to change your SQL) but lets you control exactly when data moves, just like a native table.
References
• data_source/catalog/catalog_overview.md
• sql-reference/sql-statements/View/CREATE_VIEW.md
• using_starrocks/async_mv/use_cases/query_rewrite_with_materialized_views.md
References
• data_source/catalog/catalog_overview.md
• sql-reference/sql-statements/View/CREATE_VIEW.md
• using_starrocks/async_mv/use_cases/query_rewrite_with_materialized_views.md
• data_source/catalog/default_catalog.md
ReferencesKenneth Oh
07/29/2026, 1:52 AMRocky
07/29/2026, 1:53 AMsql
CREATE TABLE my_table (
id BIGINT NOT NULL,
name VARCHAR(65533),
...
) PRIMARY KEY (id)
DISTRIBUTED BY HASH(id)
PROPERTIES (
"enable_persistent_index" = "true",
"persistent_index_type" = "CLOUD_NATIVE" -- Recommended for shared-data
);
Limitations to Keep in Mind
* Hybrid Row-Column Storage: As mentioned previously, the specialized row-store property ("store_row_column" = "true") is not yet supported in shared-data mode, even in v4.1.
* Index Warmup: Because data and indexes are stored on S3, the first few queries after a node restart or cache eviction may be slower while the index is being pulled from object storage into the local cache.
References
• deployment/shared_data/feature-support-shared-data.md
• table_design/table_types/primary_key_table.md
• sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE.md
References
• deployment/shared_data/feature-support-shared-data.md
• table_design/table_types/primary_key_table.md