<@U0A71G31CDV> I am trying to access Snowflake's i...
# questions-and-troubleshooting
c
@Rocky I am trying to access Snowflake's internal Horizon REST catalog. It uses Polaris under the hood, but with slight differences in config, using a PAT instead of client id and secret for access token. Here is example config
Copy code
CREATE EXTERNAL CATALOG horizon
PROPERTIES (
    "iceberg.catalog.uri"  = "<https://my-account.snowflakecomputing.com/polaris/api/catalog>",
    "type"  =  "iceberg",
    "iceberg.catalog.type"  =  "rest",
    "iceberg.catalog.warehouse" = "MY_DATABASE",
    "iceberg.catalog.security" = "oauth2",
    "iceberg.catalog.client.region" = "us-east-1",
    "iceberg.catalog.oauth2.credential" = "eyJraWQiOi...",
    "iceberg.catalog.oauth2.scope"='session:role:MY_SCOPED_ROLE',
    "vended-credentials-enabled"="true"
 );
I have successfully tested the credentials using
curl
to obtain an access token and use it to get table metadata. In StarRocks 4.0.8, I can
show databases
and it brings up a list of databases including MY_DATABASE. But when I try to run anything deeper, such as `show tables in
<http://MY_DATABASE.MY|MY_DATABASE.MY>_SCHEMA
I get errors in log saying client denied.
r
Hello! I'm Rocky. Based on your configuration and the symptoms you're describing, it sounds like you're very close to getting the Snowflake Horizon (Polaris) catalog working. The "client denied" error when running
show tables
(while
show databases
works) usually occurs because Snowflake Horizon/Polaris requires nested namespace handling and specific access delegation settings that are not enabled by default in StarRocks. Here are the specific configuration adjustments you should make: 1. Enable Nested Namespaces Snowflake uses a hierarchical structure (Database -> Schema -> Table). By default, StarRocks might try to treat
MY_DATABASE.MY_SCHEMA
as a single-level namespace string. For Polaris-based catalogs like Horizon, you must explicitly enable nested namespace support:
Copy code
sql
"iceberg.catalog.rest.nested-namespace-enabled" = "true"
2. Correct Property Names In StarRocks, properties for the Iceberg REST catalog should consistently use the
iceberg.catalog.
prefix. In your snippet,
vended-credentials-enabled
was missing the prefix. • Change
"vended-credentials-enabled" = "true"
to
"iceberg.catalog.vended-credentials-enabled" = "true"
. 3. Add the Access Delegation Header Snowflake Horizon often expects a specific header to explicitly request vended credentials (temporary S3/GCS keys). You can pass this via the
rest.header
property:
Copy code
sql
"iceberg.catalog.rest.header.X-Iceberg-Access-Delegation" = "vended-credentials"
4. Verify Warehouse Name For Snowflake Horizon, the
iceberg.catalog.warehouse
property must typically match your Snowflake Account Locator (e.g.,
ORG-ACCOUNT
) or the specific Snowflake Database name, depending on your endpoint level. If
show databases
is showing the database name, ensure the warehouse matches the expected Polaris warehouse identifier. Recommended Configuration Example Try recreating your catalog with these refined properties:
Copy code
sql
CREATE EXTERNAL CATALOG horizon
PROPERTIES (
    "type" = "iceberg",
    "iceberg.catalog.type" = "rest",
    "iceberg.catalog.uri" = "https://<my-account>.<http://snowflakecomputing.com/polaris/api/catalog|snowflakecomputing.com/polaris/api/catalog>",
    "iceberg.catalog.warehouse" = "MY_DATABASE", -- Ensure this is correct
    "iceberg.catalog.security" = "oauth2",
    "iceberg.catalog.oauth2.credential" = "eyJraWQiOi...", -- Your PAT
    "iceberg.catalog.oauth2.scope" = "session:role:MY_SCOPED_ROLE",
    
    -- Critical for Snowflake/Polaris
    "iceberg.catalog.rest.nested-namespace-enabled" = "true",
    "iceberg.catalog.vended-credentials-enabled" = "true",
    "iceberg.catalog.rest.header.X-Iceberg-Access-Delegation" = "vended-credentials",
    
    -- Storage Region
    "aws.s3.region" = "us-east-1"
);
Why
show databases
worked but
show tables
failed?
show databases
: This calls the
GET /v1/namespaces
endpoint. This is a top-level call that often succeeds even if nested namespace support is off, as it returns the first level of the hierarchy. •
show tables
: This calls
GET /v1/namespaces/{ns}/tables
. Without
nested-namespace-enabled
, StarRocks sends
{ns}
as a single string (e.g.,
MY_DATABASE.MY_SCHEMA
). Snowflake expects a nested path (e.g.,
.../namespaces/MY_DATABASE/namespaces/MY_SCHEMA/tables
). This mismatch or the missing delegation header often results in the "client denied" (403 Forbidden) response from Snowflake. Note on Version: You mentioned StarRocks 4.0.8. While 4.0 is the upcoming major version focusing on "Catalog-Centric" security and improved vended credentials, if you are actually on a 3.4.x release, these properties still apply and are the standard way to fix REST connectivity issues with Polaris. Referencesdata_source/catalog/iceberg/iceberg_rest_security.mddata_source/catalog/iceberg/iceberg_catalog.md
c
@Rocky I made the changes you suggested but still fails, and with "iceberg.catalog.rest.nested-namespace-enabled" = "true" each statement takes 2.5 minutes. WIll I have better luck with 4.1?
r
The short answer is yes, StarRocks 4.1 includes significant optimizations and bug fixes for the Iceberg REST catalog that directly address the performance and connectivity issues you're seeing with Snowflake Horizon (Polaris). The 2.5-minute delay and "client denied" error in 4.0.8 are known behaviors related to how StarRocks traverses the hierarchical namespace in Snowflake. Here is why this is happening and why 4.1 is a better choice: 1. Why it's slow (2.5 minutes) In StarRocks 4.0, when
iceberg.catalog.rest.nested-namespace-enabled
is set to
true
, the engine often performs a recursive listing of all namespaces to resolve the hierarchy for a command like
SHOW TABLES
. * The Problem: Snowflake Horizon's API can be slow to return deep recursive results, or StarRocks might be triggering multiple retries after internal 60-second timeouts. * The 4.1 Improvement: StarRocks 4.1 introduces Optimized Metadata Caching and a more efficient lookup strategy for REST catalogs. Instead of broad recursive scans, it uses targeted namespace calls that significantly reduce the "time to first byte" for metadata operations. 2. Why "Client Denied" occurs Even if your
curl
test worked, the StarRocks FE might be appending an incorrect suffix to the URI or using a different namespace path format when
nested-namespace-enabled
is active. * Snowflake requires a very specific path:
.../namespaces/DATABASE/namespaces/SCHEMA/tables
. * If the catalog property
iceberg.catalog.warehouse
is not set exactly to your Snowflake Account Locator (the one found in your URL, e.g.,
ORG-ACCOUNT
), Snowflake may deny the request at the table level even if it allows the database-level listing. 3. Recommended Adjustments for 4.1 When you move to 4.1, use this refined configuration. Note the addition of the
allowall
access control property, which ensures StarRocks doesn't block queries before they even reach Snowflake:
Copy code
sql
CREATE EXTERNAL CATALOG horizon
PROPERTIES (
    "type" = "iceberg",
    "iceberg.catalog.type" = "rest",
    "iceberg.catalog.uri" = "https://<account>.<http://snowflakecomputing.com/polaris/api/catalog|snowflakecomputing.com/polaris/api/catalog>",
    
    -- IMPORTANT: For Horizon, this should be your Snowflake Account Locator (e.g. MYORG-MYACCT)
    "iceberg.catalog.warehouse" = "MY_DATABASE", 
    
    "iceberg.catalog.security" = "oauth2",
    "iceberg.catalog.oauth2.credential" = "eyJraWQiOi...",
    "iceberg.catalog.oauth2.scope" = "session:role:MY_SCOPED_ROLE",
    
    -- Optimization properties in 4.1
    "iceberg.catalog.rest.nested-namespace-enabled" = "true",
    "iceberg.catalog.vended-credentials-enabled" = "true",
    "catalog.access.control" = "allowall", -- Let Snowflake handle the AuthZ
    
    -- Mandatory Header for Snowflake Vended Credentials
    "iceberg.catalog.rest.header.X-Iceberg-Access-Delegation" = "vended-credentials"
);
Troubleshooting Steps If you still see the 2.5-minute delay in 4.0.8 or 4.1: 1. Check FE Logs: Look at
fe.log
and search for
RESTClient
. You will see the exact URL StarRocks is calling. If the URL looks like
.../namespaces/MY_DATABASE.MY_SCHEMA/tables
(with a dot), then
nested-namespace-enabled
is not being respected correctly by that specific StarRocks build. 2. Verify Warehouse: Ensure the
iceberg.catalog.warehouse
property matches the "Warehouse" name defined in your Polaris/Horizon configuration. For Snowflake's internal catalog, this is usually the Snowflake Database name in uppercase. 3. Scope: Try setting
"iceberg.catalog.oauth2.scope" = "PRINCIPAL_ROLE:ALL"
if your custom role scope continues to return 403, just to rule out permission inheritance issues. Conclusion: Moving to 4.1 is highly recommended. It was specifically hardened for "Catalog-Centric" workflows (like Snowflake Horizon) where the engine delegates security and relies heavily on vended credentials. References