If you’re getting issues like below, more the Policy JSON is wrong. Here’s my advice on how to debug.
Please ensure the external volume has privileges to [write files to, list files in] the active storage location
- Where ever possible, avoid quotes, especially double quotes.
- Use a folder path prefix, /, even though it says it’s optional. This way you can use the guide and included policy wholesale instead of granting access to the entire bucket with * and having to keep modifications in your head
- the guide mentions that you can give Snowflake access to the entire bucket instead of specify the entire bucket
*
instead of - Add
STORAGE_AWS_EXTERNAL_ID
to yourEXTERNAL VOLUME DDL
so you don’t have to modify the IAM Role’s Trust Relationship after everyCREATE EXTERNAL VOLUME
- Start by editing it there AWS Policies store revisions as “versions”, so rather than creating new policies and pointing the role to it, just edit directly, you can always roll back.
- Be very careful in the policy JSON about how
Resource
names terminate- For the
Object
permissions (Put
Get
andDelete
), theResource
should contain- both
bucket
name andprefix
name - end with
/*
as in
- both
- For the
Bucket
permissions (List
andGet Location
):- the
Resource
is just the bucket name, and s3:prefix
condition should be prefix with a wildcard
- the
- For the
Maybe I’m a Snowflake newb, but….
i’m 95% certain that I created an External Volume that literally had "
in the object name. renaming with _
instead of -
solved this problem for me
also! BASE_LOCATION=""
is different from BASE_LOCATION=''=. It must be single-quoted or else Snowflake will make a literal "directory called
""`
once I added the STORAGE_AWS_EXTERNAL_ID
to the CREATE EXTERNAL VOLUME
statement, my debug iterations got faster
The error I think comes down to a struggle to disambiguate paths of things etc
- AWS Resource Identifiers within AWS IAM Policy JSON
EXTERNAL VOLUME
'sSTORAGE_BASE_URL
- should:
- include the bucket prefix, and
- not include a terminating
/
or*
wildcard
- docs give a terminal slash in the example maybe it doesn’t matter
STORAGE_BASE_URL = 's3://*bucket*[/*path*/]'
- should:
CREATE ICEBERG TABLE
’sBASE_LOCATION
is''
-
User Guide: Create an Iceberg Table
-
SQL Reference: CREATE ICEBERG TABLE
-
Quickstart: Getting Started with Iceberg Tables
-
SQL Reference:
CREATE EXTERNAL VOLUME
-
User Guide: Configure an external volume for Iceberg tables
Configure an external volume for Iceberg tables | Snowflake Documentation
-
Blog: Iceberg Tables: Powering Open Standards with Snowflake Innovations