storage.googleapis.com). The catalog type is gcs-interop and it reuses the same S3 wiring as S3 Data Lake — only the endpoint, addressing style, and credential source differ.
How it works
Onboarding is four calls. Each one feeds the next:All paths are relative to your controller base URL. The examples assume
export CONTROLLER=https://<your-controller>. On StarTree Cloud, the controller is reached through the data-plane proxy, so use export CONTROLLER=https://<data-plane-host>/api/pinot.If your controller requires authentication, add an Authorization header to every request — e.g. -H "Authorization: Bearer <token>". The examples below omit it for brevity.Prerequisites
- StarTree release with GCS External Table support enabled, and tiered storage configured on the cluster with a
GCS_INTEROPERABLEtier backend. Contact StarTree support if unsure. - Network access to the controller REST endpoint, plus an
Authorizationtoken if your cluster requires auth. - A GCS bucket with Parquet files and a GCS HMAC key (access ID + secret) with
storage.objects.getandstorage.objects.liston the bucket. Generate HMAC keys in the Google Cloud Console → Cloud Storage → Settings → Interoperability. - The GCS bucket name, key prefix, and the project’s region (used as a placeholder — GCS ignores it but the field is required).
Limitations
- HMAC keys are the only credential type — there’s no IAM-role or workload-identity option for GCS Data Lake today.
disable.integrity.protectionsmust betruefor every GCS connection — GCS’s checksum behavior differs from AWS S3’s, and the AWS SDK mis-validates it otherwise. See the Note below.- No schema evolution — same limitation as the S3 Data Lake source; a source-side column rename requires a manual schema change.
Authentication
GCS Data Lake authenticates using HMAC keys (Google’s S3-interop credentials) — there’s no assumed-role equivalent since this path goes through the AWS SDK’s S3-compatible client, not native GCP IAM. Choose one of two methods.disable.integrity.protections must be set to true for all GCS connections, regardless of method. GCS rejects the AWS SDK’s default request checksums on writes and returns whole-object checksums on range GETs that the SDK mis-validates. Setting this flag relaxes both to WHEN_REQUIRED, which is required for reads and writes to succeed.Inline HMAC keys
Quick tests, or when Secret Manager is not available. Generate HMAC keys in the Google Cloud Console → Cloud Storage → Settings → Interoperability.GCP Secret Manager (recommended for production)
accessKey/secretKey are treated as secret names rather than literal values, and resolved from GCP Secret Manager at read time — no HMAC material stored in the table config.
gcpkeypath needs Secret Manager read access to the two named secrets.
Step 1: Validate and browse the connection
POST /connections/browse
There is no separate “validate” endpoint. Browsing the catalog is the validation step: a 200 with an items list (even an empty one) confirms your credentials and connectivity.
- Set
pathto""to browse the root prefix — this both validates the connection and lists files/directories.
Request
- Inline HMAC
- GCP Secret Manager
Response
Step 2: Preview the schema
POST /tables/preview
Samples the Parquet files, infers a Pinot schema, and returns an enriched table config plus sample rows. Review it, tweak if needed, then carry the schema and config forward to steps 3 and 4.
The request and response share the same JSON shape. You send a
tableConfig describing the source; the response fills in schema, the enriched tableConfigs.offline, sampled rows, and a summary.Request
Top-level fields:config.inference — how the schema is derived:
config.sampling — how rows are sampled:
- Inline HMAC
- GCP Secret Manager
Response
Step 3: Create the schema
POST /schemas
Send the schema object from the preview response. Rename its schemaName to match your table.
Step 4: Create the table
POST /tables
Send the enriched tableConfigs.offline object from the preview response. The ExternalTableSyncTask block marks the table as external, and the tierConfigs array pins it to the GCS_INTEROPERABLE tier.
schedule (cron) interval. There is no separate start call.
The
tableConfigs.offline returned by /tables/preview includes a tierConfigs block pre-configured for GCS_INTEROPERABLE. Verify that the tier backend credentials match the source catalog credentials (they can differ if you use separate HMAC keys or Secret Manager secrets for the deep store).Quickstart: onboard a table end-to-end
The whole flow as one script (inline HMAC mode). Fill in the variables at the top, run the script, and the first sync starts automatically.0, verify it’s queryable.
Monitor onboarding
Three read-only endpoints report ingestion progress — run status, ingestion checkpoint, and source file count — and requireexecutor=controller (set automatically). See Observability for full request and response details.
Verify it’s queryable
Whenstatus is COMPLETED and segmentsUploaded matches filesDiscovered, run a query against the broker (or the Data Portal query console) to confirm the data is live:
summary.nSourceRows (preview only samples up to ~100 rows) — confirm it’s non-zero and plausible for your dataset. If status is COMPLETED but the count is 0, give segments a moment to load on the servers, then recheck; if it persists, see Troubleshooting.
GCS-specific config reference
All keys go under theExternalTableSyncTask block in taskTypeConfigsMap.
What’s next
Now that the table is created and data is loading, these are the highest-impact follow-up steps:- Add indexes for your query patterns. Without indexes, every query scans all remote Parquet data. Add a range index on time/numeric columns, an inverted index on low-cardinality filter columns, and a bloom filter on high-cardinality ID columns. → Indexes
-
Enable caching and preload. Set
enable.prefetch.page.cache=trueandpreload.enable=trueon the S3 tier so index data is served from local disk on repeated queries instead of re-fetched from S3. → Data and Index Caching - Protect large-scan queries from OOM. For tables that receive heavy aggregations or wide scans, enable the query OOM killer so a runaway query is killed instead of crashing the server. → Best Practices & Configs — Query OOM protection
- Monitor ongoing syncs. Use the observability endpoints to check run status, ingestion checkpoint, and source file count after each scheduled sync. → Observability
For common questions and failures, see the FAQ and Troubleshooting.

