Snowflake
| Status | verified |
|---|---|
| Reads | yes, on an allowed account |
| Writes | yes, on an allowed account |
| Iceberg v3 | reads and writes |
| Geometry, geography | geometry and geography, read and written |
| Last verified | 2026-10-03 (Snowflake 10.35) |
Snowflake reads and writes Iceberg tables in a LakehouseBox catalog without copying them: your agents and Snowflake work on the same tables. Snowflake talks to the catalog through a catalog integration and to the files through an external volume. The catalog half works on any Snowflake account. The external volume works only on an account where Snowflake Support has allowed our storage endpoint, which takes a support case per account (below).
Before you start: ask Snowflake Support to allow the endpoint
Snowflake accepts S3-compatible storage only from endpoints it has allowed. On an account that has not asked yet, creating the external volume fails at once:
001075 (22023): SQL compilation error: Endpoint s3.lakehousebox.com not allowed.
To get it allowed, open a case from your Snowflake account (Snowsight, Help & support; a trial account can file one too) and ask Snowflake to allow s3.lakehousebox.com for S3-compatible external volumes on your account. Give your account name, account locator and region. Snowflake asks a storage provider to pass its S3-compatibility test suite (snowflakedb/snowflake-s3compat-api-test-suite); ours was run unmodified against LakehouseBox on 2026-09-27, 5 GiB upload included, and we can send you the result to attach. What it found:
- Passes: reads (whole and ranged), object metadata, writes with user metadata, listing 1,001 objects across pages, single and batch deletes, copies, presigned URLs, a 5 GiB upload, and AWS's exact refusals for a wrong key id, a wrong secret, no credentials and someone else's bucket. 7 of the 9 test methods pass unmodified.
- The two that differ are both about a bucket that does not exist: LakehouseBox refuses it at the TLS handshake (no certificate is issued for a bucket that does not exist, so nobody can probe which buckets exist), where AWS answers 404. Say so in the case.
Our own case was answered the next day (2026-09-28): the endpoint was allowed for that account only; allowing it for every Snowflake account is a separate review at Snowflake, not done yet. Ask us at hello@lakehousebox.com and we will help with the case.
Connect: reading
lhbox connect --catalog <catalog> --engine snowflake --show-secrets
prints two statements to run in Snowflake: CREATE CATALOG INTEGRATION lhbox_rest (the catalog, OAuth with the catalog's credential) and CREATE EXTERNAL VOLUME lhbox_s3 (STORAGE_PROVIDER = 'S3COMPAT', endpoint s3.lakehousebox.com, ALLOW_WRITES = FALSE). Set CATALOG_NAMESPACE to your namespace. Then each table is one statement:
CREATE ICEBERG TABLE cities
EXTERNAL_VOLUME = 'lhbox_s3' CATALOG = 'lhbox_rest'
CATALOG_NAMESPACE = 'demo' CATALOG_TABLE_NAME = 'cities'
AUTO_REFRESH = TRUE;
Things to know:
- The key in the volume is static. Snowflake supports catalog-vended credentials only for Amazon S3, Azure and Google Cloud Storage (it sends them to AWS), so the volume holds one of the catalog's key pairs. Without
--writethat is the catalog's read-only pair, whatever level you hold: the catalog refuses its commits and the storage its writes. - Virtual-hosted bucket addresses. Snowflake addresses the bucket as
https://<bucket>.s3.lakehousebox.com, which a catalog serves only once an admin turns it on. An admin asking for the Snowflake recipe turns it on; anyone else's recipe says to ask an admin, or runlhbox catalog update <catalog> --virtual-host on. That address's TLS certificate is listed in the public Certificate Transparency logs with the bucket name. - New commits:
ALTER ICEBERG TABLE … REFRESHpicks one up at once; withAUTO_REFRESH = TRUEa commit appeared within about 30 seconds (measured 2026-09-28).
Verified 2026-09-28: tables written by PyIceberg 0.12 and DuckDB 1.5.5 read with the right sums, REFRESH and AUTO_REFRESH included.
Connect: writing
lhbox connect --catalog <catalog> --engine snowflake --write --show-secrets
You must hold write on the catalog (a read holder is refused). The recipe then carries the catalog's read/write key pair, ALLOW_WRITES = TRUE, and a catalog-linked database, in which Snowflake creates and writes tables in the catalog. Its objects are named after the catalog (lhbox_<catalog>_rw, lhbox_<catalog>_rw_s3), so it runs next to a reading recipe you already ran:
CREATE DATABASE lhbox_<catalog>
LINKED_CATALOG = ( CATALOG = 'lhbox_<catalog>_rw', ALLOWED_NAMESPACES = ('<namespace>') )
EXTERNAL_VOLUME = 'lhbox_<catalog>_rw_s3';
CREATE ICEBERG TABLE lhbox_<catalog>."<namespace>"."places"
(id INT, name STRING, geom GEOMETRY, geog GEOGRAPHY)
ICEBERG_VERSION = 3;
- The volume check. Before Snowflake writes to a location it writes, reads, lists and deletes a small test object at the bucket's root (
SELECT SYSTEM$VERIFY_EXTERNAL_VOLUME('…')runs the same check). LakehouseBox's table storage accepts only Iceberg files, with exactly one exception: that test object (at the root, at most 1 KB, no metadata). - The read/write pair stays in Snowflake. Hand it over as you would to an agent: it keeps writing after someone's access is taken away. To revoke it, rotate the catalog's credential (
lhbox catalog rotate <catalog>); every other recipe of that catalog then needs fetching again. Each time someone takes this recipe, the organisation's audit log records it (connection.static_write). - Geometry needs SRID 4326. Iceberg's default coordinate reference system maps to Snowflake's SRID 4326, so a value made with
TO_GEOMETRY(…)(SRID 0) is refused: wrap it,ST_SETSRID(TO_GEOMETRY(…), 4326).
Verified 2026-10-03: the volume check passed (write, read, list, delete); a catalog-linked database created an Iceberg v3 table with GEOMETRY and GEOGRAPHY columns and inserted 14,885 rows.
Geometry and geography
Snowflake is the most complete engine we have tested on Iceberg v3 geography:
- Spherical questions are right. "Road segments within 2 km of central Valencia" on a
geographycolumn counts 10,376, against 10,364 computed separately in a metric projection; polygons and points agree the same way. Across the antimeridian, a line from 170°E to 170°W measures 2,224 km on the sphere, where the same line as planar geometry is 340 degrees long. - It writes geography bounds. Snowflake is the only writer we tested that records the bounding box of a
geographycolumn in the table's metadata, and it gets it right on the sphere (the file with the Madrid–New York line reaches 46.3°N, where the great circle runs).
Known limitations
As measured on 2026-10-03 (Snowflake 10.35), and reported to Snowflake:
- Some geometry tables written by other engines fail to read at scale: DuckDB-written point and polygon tables (internal error 300010) and Spark-written geometry columns (a cast error). DuckDB-written line tables, every small table, and every
geographycolumn read fine. - Tables Snowflake writes record file paths as
s3compat://…. The Iceberg spec allows any scheme, but most engines do not recognise this one: Spark 4.1 with Iceberg 1.12 reads these tables, Trino 483 and PyIceberg 0.12 do not yet. - Spatial filters scan whole files. Snowflake skips files by their bounds, not row groups inside them, and with no geography bounds from other writers a spherical query reads the whole table (2.4–7.0 GB for the Overture subsets).
- Allowed account by account, until Snowflake's global review of the endpoint.