Spice v2.4.1 (Oct 29, 2026)
Spice v2.4.1 is now available! ๐ ๏ธ
Spice v2.4.1 is a patch release with MySQL connection improvements and security fixes. MySQL pools now replace each connection after 5 minutes by default. This spreads connections across the servers behind a load-balanced hostname, such as an Aurora reader endpoint. It also adds security hardening: stricter checks for internal network addresses and memory limits for untrusted input.
What's New in v2.4.1โ
MySQL Connection Poolsโ
MySQL datasets and catalogs now replace each pooled connection after mysql_connection_max_lifetime. Thus the pool spreads across the servers behind a load-balanced hostname, such as an Aurora reader endpoint. The default is 5m, and 0s keeps connections open. Idle connections above mysql_pool_min stay open for 30 seconds after their last use, so queries that follow each other closely reuse a connection.
With mysql_connection_string, mysql_pool_min and mysql_pool_max now apply. See MySQL deployment.
Each MySQL pool logs the server that its new connections reached, with the Aurora instance on Aurora MySQL:
MySQL dataset 'orders' opened connection 12345 to 'reader.example.internal:3306', which reached server 'ip-10-0-1-23:3306' (Aurora instance 'app-reader-2').
The line is INFO the first time in 10 minutes that a pool reaches a server, and DEBUG after that.
Slow-Refresh Warningsโ
Accelerated datasets and views now log one warning while a full or append refresh runs slower than usual. This applies to every data source, not only MySQL. Spice compares the refresh with the median of the last 10 successful refreshes in the same mode. The threshold is the larger of 3 times and 30 seconds more than that median. The warning needs 3 earlier refreshes and has no setting:
Refresh of dataset 'orders' has run for 1m 3s, more than 3 times the 21s its last 3 full refreshes took at the median, so its accelerated data is falling further behind the source than usual. ...
See Data Refresh.
Internal Addresses Are Refused for Catalog Storage, HTTP Redirects, and URL Tablesโ
Spice no longer sends a request to a private, loopback, or link-local address only because a data source names that address. The checks apply to these paths:
- Iceberg REST catalogs: Spice refuses a storage endpoint or region that the catalog vends when it differs from the Spicepod value and reaches an internal host. Spice connects only to the addresses that its DNS check approved. Spice refuses a redirect from vended storage to an internal host, and it removes
AuthorizationandCookieheaders when a redirect changes the origin. - AWS Glue: Spice rejects a table location that is not
s3://. - HTTP and HTTPS datasets: A redirect to a host name that resolves to an internal address fails with
Refused to connect to <host>. - URL tables: With
runtime.params.url_tables: enabled, Spice checks every redirect and every resolved address. Ans3,abfs,abfss,gs, orgcsURL table cannot set an endpoint or credentials in the URL fragment.
Storage endpoints and regions that the Spicepod sets keep working. SPICE_URL_TABLE_ALLOW_PRIVATE_HOSTS=true turns off the checks for Iceberg and URL tables. See Breaking Changes for the setups that need a setting.
HTTP Connector Passwords Stay out of Errorsโ
Errors from http and https file datasets no longer include the password from the URL. This applies to the warning log, /v1/datasets?status=true, and Cloud Connect. Spice now sends the user name and http_password in an Authorization: Basic header, only to the origin that the dataset configures. CSV, Parquet, and other file reads through the HTTP connector now authenticate, and the server no longer answers them with 401.
Compressed HTTP Responses Have a Limitโ
Spice refuses a compressed HTTP response after it decodes more than 64 MiB at more than 100 times the bytes received. In a test, a 583 KB gzip response grew the runtime to 2,464 MB of memory. With this fix, the runtime refused the response at 232 MB. The check applies to the HTTP connector, OAuth2 token exchange, Unity Catalog, Databricks, and the Debezium schema registry. Token and metadata responses also have a 128 MiB limit on decoded size.
Flight SQL Rejects Forged Handles and Oversized IPC Messagesโ
Spice now signs each Flight SQL prepared statement handle with a keyed BLAKE3 tag, and it rejects a handle that does not verify. A client could build a handle by hand. Then a few hundred bytes of parameters made the Arrow IPC decoder allocate any size. In a test, one 389-byte GetFlightInfo request grew the runtime to 15 GB, and the kernel stopped it. A handle is valid only on the runtime process that issued it. See Breaking Changes.
Spice also refuses a compressed Arrow IPC message that declares more than 64 MiB and more than 100 times its compressed body. This applies to Flight SQL parameters, Flight DoPut, and the spice.ai and flightsql connectors.
Memory Limits for Untrusted Files, MCP Tool Results, and Scalar Functionsโ
A small malformed file or a single query can no longer make the runtime allocate gigabytes of memory or crash:
- Parquet pages: A page that declares more than 64 MiB and more than 1,000 times its compressed bytes fails with an error. In a test, 8 concurrent scans of a 34 KB file used 4,271 MiB of memory. With this fix, they used 166 MiB.
- Parquet metadata: A footer list that declares more elements than the file can hold fails with a decode error. In a test, one malformed footer used 22.6 GiB of memory. With this fix, it used 0.43 GiB.
- Parquet schema depth: A schema that nests more than 100 levels fails with
Parquet schema nesting depth exceeds the maximum of 100. A deeper schema overflowed the stack and stopped the runtime. - ORC metadata: A metadata stream that decodes to more than 64 MiB and more than 100 times its compressed size fails with an error. In a test, a 1 MiB ORC file used 6.07 GiB of memory. With this fix, it used 337 MiB.
- ORC type tree: A footer type tree that nests more than 100 levels, or that uses a type more than once, fails with an error. A deeper tree overflowed the stack and stopped the runtime.
- DOCX, XLSX, PPTX, and PDF documents: A document fails with
DocumentTooLargepast 64 MiB for one ZIP entry, 256 MiB decompressed in total, or 64 MiB of extracted text. In a test, a 1.2 MB DOCX file used 6.1 GiB of memory. With this fix, it used 0.27 GiB. - MCP tool results: An MCP tool call fails when the result is larger than 16 MiB. The runtime logs a warning that names the MCP server. In a test, a 200 MB result used 2,423 MB more memory. With this fix, it used less than 1 MB more.
- Scalar functions:
repeat,lpad,rpad,array_repeat,array_resize,range, andgenerate_seriesreserve their output fromruntime.query.memory_limit. A call that does not fit fails withResources exhausted. In a test with a 512 MiB limit,length(repeat('a', 1e9))used 3.9 GB. With this fix, the query failed, and peak memory was 97 MB.
Read-Only API Keys Are Refused Earlier on Write Pathsโ
A read-only API key now gets 403 API key does not allow write access on a write route before Spice reads the request body. A malformed body got a parsing error that named the required fields of the route. A read-only key also can no longer export OpenTelemetry metrics through gRPC on the Flight port.
Request Headers No Longer Create Metric Seriesโ
Spice no longer copies User-Agent or W3C baggage values into metric labels. Any caller could send these headers, also to /health, and each distinct value created new series in memory. In a test, 500 requests with distinct values grew /metrics from 365 to 34,865 series. With this fix, the count stays at 365. The client label now has a fixed set of values. Refer to Breaking Changes.
WASM User-Defined Functions on arm64 (GHSA-mghf-wjfp-p5xm)โ
Wasmtime 48.0.7 fixes a sandbox escape for WASM user-defined functions on arm64 hosts. On aarch64, the Cranelift compiler could jump to the wrong target for a large Wasm br_table instruction. The advisory is GHSA-mghf-wjfp-p5xm. It does not affect x86_64 hosts.
TLS Certificate Reload Rejects a Mismatched Keyโ
A certificate rotation no longer breaks TLS handshakes when the new certificate does not match the private key. The runtime keeps the current certificate, logs a warning that names both files, and increments runtime_tls_reload_total{result="key_mismatch"}. At startup, a mismatched pair stops the runtime. See TLS.
The spice CLI HTTP commands, such as status, datasets, and refresh, now trust the CA in --tls-root-certificate-file. A certificate failure reports the TLS error and a fix, not The Spice runtime is unavailable.
Docker Images Get Current Packagesโ
Each release build of the spiceai/spiceai image now runs apt-get upgrade. The build cache can no longer reuse a package layer from before a security update, such as DSA-6572-1. The CUDA image moves from nvidia/cuda:12.6.0-cudnn-runtime-ubuntu24.04, from August 2024, to 12.9.2 with current packages.
Dependency Updatesโ
wasmtime: 47.0.3 โ 48.0.7. This update fixes GHSA-mghf-wjfp-p5xm.rustls: 0.23.45 โ 0.23.46.aws-lc-rs: 1.18.1 โ 1.18.2. The bundled AWS-LC moves from v5.7.0 to v5.11.0.webpki-root-certs: 1.0.10 โ 1.0.11. This update removes theemSign Root CA - C1andemSign ECC Root CA - C3roots. v2.4.0 already removed them fromwebpki-roots.http-body-limit: a new crate that limits decoded HTTP response bodies.arrow-rs(Spice fork):2e2cc330โ2124b9e8. This update adds the Parquet page, metadata, and schema-depth limits. Arrow remains at v59.3.0.orc-rust: 0.9.0 โ the Spice fork atd9632e7a. This update adds the ORC metadata and type-tree limits.- CUDA Docker image base:
nvidia/cuda12.6.0 โ 12.9.2.
DataFusion remains at v55.2.0 and Arrow remains at v59.3.0.
Contributorsโ
Breaking Changesโ
MySQL pool. A dataset with mysql_connection_string and no pool settings uses 1 to 5 connections, not 10 to 100. Set mysql_pool_max if the dataset needs more concurrent queries. A non-integer or conflicting pool setting now fails the dataset.
Iceberg and Glue storage endpoints. Spice refuses a catalog-vended endpoint on an internal host, with an error that names the endpoint. These setups need a change:
- A REST catalog, such as a local Nessie, vends a private or loopback MinIO endpoint. Set
iceberg_s3_endpointandiceberg_s3_region. - A REST catalog vends only a region, and S3 resolves to private addresses through a VPC interface endpoint. Set
iceberg_s3_endpointto the regional S3 endpoint. - A Glue table location is
s3a://,http://, orhttps://. Use ans3://location.
URL table fragments. A URL table cannot set endpoint, allow_http, access keys, or proxy settings in the URL fragment. region, url_style, auth, account, and client_timeout still work. Configure a dataset for a custom endpoint. A URL table behind a proxy on a private address needs SPICE_URL_TABLE_ALLOW_PRIVATE_HOSTS=true.
Compressed HTTP responses. Very sparse rows can compress at more than 100:1, and Spice refuses them past 64 MiB. To turn off the check for a dataset, add Accept-Encoding: identity to http_headers.
Metric labels. The runtime no longer records the user_agent, client_version, client_system, or baggage labels. The client label is one of spice, repl, spicepy, spice-rs, gospice, spice.js, spice-java, spice-dotnet, or other. Update dashboards and alerts that use these labels.
Flight SQL prepared statements. A prepared statement handle is valid only on the runtime process that issued it. After a restart, or on another replica without session affinity, the client must prepare the statement again.
Documents. An XLSX file that lists cells out of document order fails with an error. A PDF that uses LZWDecode or an indirect /Filter reference is rejected.
Memory limits. Parquet, ORC, and document files past the limits in Memory Limits fail to load. MCP tool results larger than 16 MiB fail. Queries with these scalar functions fail when their output does not fit runtime.query.memory_limit.
TLS and the CLI. The runtime does not start when the TLS certificate does not match its private key. A missing or invalid --tls-root-certificate-file fails the CLI command.
Cookbook Updatesโ
No new cookbook recipes.
The Spice Cookbook provides recipes to help you get started with Spice.
Upgradingโ
To upgrade to v2.4.1, use one of the following methods:
CLI:
spice upgrade
Homebrew:
brew upgrade spiceai/spiceai/spice
Docker:
Pull the spiceai/spiceai:2.4.1 image:
docker pull spiceai/spiceai:2.4.1
For available tags, see DockerHub.
Helm:
helm repo update
helm upgrade spiceai spiceai/spiceai --version 2.4.1
AWS Marketplace:
Spice is available in the AWS Marketplace.
What's Changedโ
Changelogโ
- build(deps): bump aws-lc-rs from 1.18.1 to 1.18.2 in the aws-sdk group by @app/dependabot in #15266
- Send HTTP connector credentials as an Authorization header, not in the URL by @phillipleblanc in #15305
- fix(deps): bound Parquet page allocation by bumping the arrow-rs fork by @phillipleblanc in #15321
- Bound decompressed size of OOXML and PDF documents by @phillipleblanc in #15316
- fix(http): check write access before reading the request body on write routes by @phillipleblanc in #15326
- fix(deps): bound Parquet metadata allocation by bumping the arrow-rs fork by @phillipleblanc in #15331
- Cap MCP tool results at 16 MiB by @phillipleblanc in #15350
- fix(iceberg,glue): refuse internal storage hosts supplied by catalogs by @phillipleblanc in #15352
- fix(otlp): deny a read-only API key on gRPC metrics export by @phillipleblanc in #15351
- Refuse compressed HTTP response bodies that expand past a 100:1 ratio by @phillipleblanc in #15327
- fix(url-table): SSRF hardening for url tables by @phillipleblanc in #15354
- fix(flight): integrity-protect Flight SQL prepared statement handles by @phillipleblanc in #15347
- fix(https): refuse redirects to hosts that resolve to internal addresses by @phillipleblanc in #15594
- fix(metrics): keep request header values out of metric labels by @phillipleblanc in #15591
- fix(datafusion): hold argument-sized scalar function output to the query memory limit by @phillipleblanc in #15592
- fix: bound ORC metadata decompression by @phillipleblanc in #15608
- fix(iceberg): connect vended storage only to the addresses its DNS check approved by @phillipleblanc in #15430
- build(deps): bump wasmtime from 47.0.3 to 48.0.7 by @app/dependabot in #15671
- build(deps): bump rustls from 0.23.45 to 0.23.46 by @app/dependabot in #15696
- fix(flight): refuse compressed Arrow IPC messages with an implausible decompressed size by @phillipleblanc in #15743
- fix: limit Parquet schema nesting depth by @phillipleblanc in #15718
- fix: limit ORC footer type tree depth and size by @phillipleblanc in #15763
- fix(docker): refresh the CUDA release image base and packages by @lukekim in #15787
- fix(docker): refresh the release image apt layer on every release build by @lukekim in #15788
- fix(deps): bump webpki-roots and webpki-root-certs to 1.0.11 by @lukekim in #15789
- fix(tls): reject a reloaded certificate that doesn't match its private key by @lukekim in #15755
- fix(cli): honor --tls-root-certificate-file in HTTP commands and report certificate failures by @lukekim in #15756
- feat(mysql): connection lifetime, pool settings with a connection string, slow-refresh warning, and connection server log by @lukekim in #15792
- fix(document_parse): read a % inside a multi-line literal string as string text by @lukekim in #15807
- fix(mysql): keep idle pooled connections for 30s so back-to-back queries stop reconnecting by @lukekim in #15813
Full Changelog: https://github.com/spiceai/spiceai/compare/v2.4.0...v2.4.1

