The S3 Data Connector enables federated SQL querying on files stored in S3 or S3-compatible systems (e.g., MinIO, Cloudflare R2).
If a folder path is specified as the dataset source, all files within the folder will be loaded.
File formats are specified using the file_format parameter, as described in File Formats (opens in a new tab).
Query a public S3 dataset with no authentication:
For private buckets, add authentication (see Authentication (opens in a new tab)):
fromS3-compatible URI to a folder or file, in the format s3://<bucket>/<path>
Example: from: s3://my-bucket/path/to/file.parquet
nameThe dataset name. This will be used as the table name within Spice.
Example:
The dataset name cannot be a reserved keyword (opens in a new tab).
params| Parameter Name | Description |
|---|---|
file_format | Specifies the data format. Required if it cannot be inferred from the object URI. Options: parquet, orc, csv, json, snapshot. Refer to File Formats (opens in a new tab) for details. snapshot reads acceleration snapshots that another Spice instance publishes; see Serve a dataset from published snapshots (opens in a new tab). |
s3_endpoint | S3 endpoint URL (e.g., for MinIO). Default is the region endpoint. E.g. s3_endpoint: https://my.minio.server |
s3_url_style | URL style used for S3 requests. Options: vhost and path. When not set, auto-detected: IP endpoints use path; other custom endpoints are detected via DNS lookup on the virtual-hosted hostname; standard AWS endpoints use , except buckets whose name contains a dot, which use . |
For additional CSV, JSON, and Parquet specific parameters, see File Formats (opens in a new tab).
s3_url_styleThe S3 connector supports two request URL styles:
vhost: https://<bucket>.<endpoint>/<key> (virtual-hosted)path: https://<endpoint>/<bucket>/<key> (path-style)When s3_url_style is not set, the connector auto-detects the correct style:
http://192.168.1.100:9000) → path<bucket>.<host>. If the name resolves, vhost is used; otherwise path.vhost, except a bucket whose name contains a dot (e.g. my.bucket.name), which uses path.A dotted bucket name cannot use virtual-hosted style over HTTPS on standard AWS: the bucket becomes part of a multi-label hostname (my.bucket.name.s3.<region>.amazonaws.com) that the AWS wildcard certificate (*.s3.<region>.amazonaws.com) cannot match, so the TLS handshake fails. The connector defaults these buckets to path style, matching AWS's own recommendation (opens in a new tab). An explicit s3_url_style always takes precedence.
Set s3_url_style explicitly to skip auto-detection.
An accelerated S3 prefix can refresh from S3 Event Notifications (opens in a new tab) delivered to an Amazon SQS queue instead of on a polling interval. Set refresh_mode: changes and s3_changes_queue_url. Spice long-polls the queue and, for each s3:ObjectCreated:* notification, reads the new object and appends its rows to the acceleration.
This is object-level, not row-level, change data capture. A new object adds rows; a removed object never deletes individual rows. For the list-and-poll alternative, see append refresh (opens in a new tab) with time_column: last_modified.
When the acceleration is empty, Spice lists the from prefix once and loads every object it finds before it marks the dataset ready. On a restart with a non-empty acceleration, Spice lists the prefix once and replaces the acceleration with that listing, rather than appending every listed object again. If any listed object cannot be read, Spice neither loads nor replaces from the partial listing, and retries.
After that, Spice applies notifications from the queue:
s3:ObjectCreated:* reads the object and appends its rows as one write. A key that Spice has already applied is acknowledged without appending it again, so SQS redelivery and an overlap between the listing and the queue do not duplicate rows. The SQS message is deleted after the rows are written (at-least-once delivery).s3:ObjectRemoved:* is acknowledged and ignored by default, so queries still return the removed object's rows. With s3_on_object_removed: rebuild, Spice lists the prefix and replaces the whole acceleration from it._SUCCESS marker or a file that does not match file_format or file_extension, are acknowledged without loading.Every s3_changes_backfill_interval (default 1h), Spice lists the prefix again and applies objects it has not yet applied. SQS keeps unconsumed messages for 4 days by default and up to 14 days, so notifications sent while Spice is stopped are still delivered on restart; the backfill covers notifications that expired or were never delivered.
Spice accepts direct S3-to-SQS notifications, S3 notifications wrapped by Amazon SNS (S3 → SNS → SQS), and Amazon EventBridge S3 events. s3:TestEvent messages are ignored.
s3.amazonaws.com service principal to call sqs:SendMessage for the bucket. Without it, S3 cannot deliver notifications to the queue. See Granting permissions to publish event notification messages to a destination (opens in a new tab).s3:ObjectCreated:* to the queue. Add s3:ObjectRemoved:* only when s3_on_object_removed: rebuild is set.s3:GetObject and s3:ListBucket on the prefix, and sqs:ReceiveMessage and sqs:DeleteMessage on the queue.The SQS client uses the same credentials as the S3 connector (s3_auth, s3_key, s3_secret, s3_session_token, or the IAM role chain).
Spice refuses to register the dataset when:
refresh_mode: changes is set without s3_changes_queue_url, or s3_changes_queue_url is set without refresh_mode: changes.s3_changes_queue_url is empty, is an ARN, or is not an HTTPS SQS queue URL.s3_auth is public. An unauthenticated client cannot receive from SQS.s3_changes_region, the queue URL, or s3_region.s3_on_object_removed is not ignore or rebuild, s3_changes_key_prefix is not under the from prefix, or s3_changes_backfill_interval is not a duration greater than 0.file_format, file_extension, or the path.For example, an ARN in s3_changes_queue_url fails with:
Failed to register dataset events (s3): `s3_changes_queue_url` must be an SQS queue URL (https://sqs.<region>.amazonaws.com/...), not an ARN. See: https://spiceai.org/docs/components/data-connectors/s3
s3_on_object_removed: rebuild replaces the whole acceleration from the prefix.s3:ObjectCreated:* for an overwrite, and s3_on_object_removed: rebuild acts only on s3:ObjectRemoved:*. Write changed data to a new key, or restart Spice to replace the acceleration from a listing of the prefix.. or .. path segment is skipped by both the queue and the listing.No authentication is required for public endpoints. For private buckets, set s3_auth to key or iam_role.
If s3_auth is set to iam_role, the connector will automatically load credentials from the following sources in order.
Environment Variables:
AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN (if using temporary credentials)Shared AWS Config/Credentials Files:
Config file: ~/.aws/config (Linux/Mac) or %UserProfile%\.aws\config (Windows)
Credentials file: ~/.aws/credentials (Linux/Mac) or %UserProfile%\.aws\credentials (Windows)
The AWS_PROFILE environment variable can be used to specify a named profile, otherwise the [default] profile is used.
Supports both static credentials and SSO sessions
Example credentials file:
:::tip To set up SSO authentication:
aws configure sso to configure a new SSO profileAWS_PROFILE=sso-profileaws sso login --profile sso-profile to start a new SSO session
:::AWS STS Web Identity Token Credentials:
The connector will try each source in order until valid credentials are found. If no valid credentials are found, an authentication error will be returned.
:::note[IAM Permissions]
Regardless of the credential source, the IAM role or user must have appropriate S3 permissions (e.g., s3:ListBucket, s3:GetObject) to access the files. If the Spicepod connects to multiple different AWS services, the permissions should cover all of them.
:::
:::note[kube2iam]
kube2iam (opens in a new tab) is a project that provides IAM roles to Kubernetes pods based on annotations. It has been superceded by IAM Roles for service accounts (IRSA) (opens in a new tab), which should be preferred for new deployments.
Spice requires kube2iam >= 0.12 - versions prior to 0.12 (opens in a new tab) only supported IMDSv1.
:::
Minimum IAM policy for S3 access:
| Permission | Purpose |
|---|---|
s3:ListBucket | Required. Allows scanning all objects from the bucket |
s3:GetObject | Required. Allows fetching objects |
Refer to Object Store Data Types (opens in a new tab) for data type mapping from object store files to arrow data type.
Create a dataset named taxi_trips from a public S3 folder.
Create a dataset named cool_dataset from a Parquet file stored in MinIO.
Hive partitioning is a data organization technique that improves query performance by storing data in a hierarchical directory structure based on partition column values. This enables efficient data retrieval by skipping unnecessary data scans.
For example, a dataset partitioned by year, month, and day might have a directory structure like:
Spice can automatically infer these partition columns from the directory structure when hive_partitioning_enabled is set to true.
Use schema_source_path to speed up dataset registration by specifying a URL to use to infer the schema.
Metadata columns expose per-file S3 object metadata (_location, _last_modified, _size) as virtual columns in query results. See Metadata Columns (opens in a new tab) for full details.
Query metadata alongside regular data:
Filter by specific file:
Aggregate per file:
Spice integrates with multiple secret stores to help manage sensitive data securely. For detailed information on supported secret stores, refer to the secret stores documentation (opens in a new tab). Additionally, learn how to use referenced secrets in component parameters by visiting the using referenced secrets guide (opens in a new tab).
:::warning[Performance Considerations]
When using the S3 Data connector without acceleration, data is loaded into memory during query execution. Ensure sufficient memory is available, including overhead for queries and the runtime, especially with concurrent queries.
Memory limitations can be mitigated by storing acceleration data on disk, which is supported by duckdb (opens in a new tab) and sqlite (opens in a new tab) accelerators by specifying mode: file.
Each query retrieves data from the S3 source, which might result in significant network requests and bandwidth consumption. This can affect network performance and incur costs related to data transfer from S3.
:::
vhostpaths3_region | S3 bucket region. Default: us-east-1. |
client_timeout | Optional. Timeout for S3 operations. Defaults to 30s (the underlying object store HTTP client default) when unset. |
hive_partitioning_enabled | Enable partitioning using hive-style partitioning from the folder structure. Defaults to false |
s3_auth | Authentication type. Options: public, key and iam_role. When unset, uses the default AWS credential chain (IAM-based authentication). Set to public for unauthenticated access to public buckets. If set to key the s3_key and s3_secret parameters must also be set. If set to iam_role the credentials will be loaded from environment variables or IAM roles (see Authentication (opens in a new tab) for details). |
s3_iam_role_source | Optional. IAM role credential source (used when s3_auth is iam_role or unset). auto (default) uses the default AWS credential chain, metadata uses only instance/container metadata (IMDS, ECS, EKS/IRSA), env uses only environment variables. |
s3_key | Access key (e.g. AWS_ACCESS_KEY_ID for AWS). Requires s3_auth is set to key. |
s3_secret | Secret key (e.g. AWS_SECRET_ACCESS_KEY for AWS). Requires s3_auth is set to key. |
s3_session_token | Session token (e.g. AWS_SESSION_TOKEN for AWS) for temporary credentials. Requires s3_auth is set to key. |
s3_versioning | Enables support for S3 buckets with S3 Versioning (opens in a new tab). Options: enabled and disabled. Defaults to enabled. |
allow_http | Enables insecure HTTP connections to s3_endpoint. Defaults to false. |
schema_source_path | Specifies the URL used to infer the dataset schema. Default to the most recently modified file |
refresh_skip | Controls skipping refreshes for accelerated single-file S3 datasets when the cached ETag / version ID still matches the object in S3. Options: enabled and disabled. Defaults to enabled. Has no effect on directory (prefix) datasets or on datasets without acceleration. |
s3_changes_queue_url | SQS queue URL that receives this dataset's S3 event notifications. Required with refresh_mode: changes, and rejected without it. Must be a queue URL (https://sqs.<region>.amazonaws.com/<account>/<queue>), not an ARN. Stored as a secret. See Event-driven refresh with SQS (opens in a new tab). |
s3_changes_region | Optional. AWS region of the SQS queue. Defaults to the region in s3_changes_queue_url, then s3_region. |
s3_changes_key_prefix | Optional. Object-key prefix to apply from the queue and the listing backfill. Defaults to the key prefix of from. Must be equal to or nested under the dataset path. |
s3_changes_backfill_interval | Optional. How often Spice lists the dataset prefix and applies objects it has not yet applied, so missed or expired notifications still load. A duration greater than 0. Defaults to 1h. |
s3_on_object_removed | Optional. What to do with s3:ObjectRemoved:* notifications. ignore (default) keeps the removed object's rows. rebuild replaces the whole acceleration from a listing of the prefix; it does not delete individual rows. |
fromfrom contains a wildcard or names a single object instead of a prefix. End the prefix with /; keep a single object on refresh_mode: full.AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_ARN to be present.
ECS Container Credentials:
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI or AWS_CONTAINER_CREDENTIALS_FULL_URI which are automatically injected by ECS.AWS EC2 Instance Metadata Service (IMDSv2):