date: 2026-11-02 title: 'Spice v2.4.1 (Oct 29, 2026)' type: blog authors: [krinart] tags: [release, mysql, security, iceberg, http, parquet, flight-sql, tls, metrics]
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.
MySQL (opens in a new tab) 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 (opens in a new tab).
Each MySQL pool logs the server that its new connections reached, with the Aurora instance on Aurora MySQL:
The line is INFO the first time in 10 minutes that a pool reaches a server, and DEBUG after that.
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:
See Data Refresh (opens in a new tab).
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:
Authorization and Cookie headers when a redirect changes the origin.s3://.Refused to connect to <host>.runtime.params.url_tables: enabled, Spice checks every redirect and every resolved address. An s3, abfs, abfss, gs, or gcs URL 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 (opens in a new tab) for the setups that need a setting.
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.
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.
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 (opens in a new tab).
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.
A small malformed file or a single query can no longer make the runtime allocate gigabytes of memory or crash:
Parquet schema nesting depth exceeds the maximum of 100. A deeper schema overflowed the stack and stopped the runtime.DocumentTooLarge past 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.repeat, lpad, rpad, array_repeat, array_resize, range, and generate_series reserve their output from runtime.query.memory_limit. A call that does not fit fails with Resources 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.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.
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 (opens in a new tab).
Wasmtime 48.0.7 fixes a sandbox escape for WASM user-defined functions (opens in a new tab) 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 (opens in a new tab). It does not affect x86_64 hosts.
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 (opens in a new tab).
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.
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 (opens in a new tab). The CUDA image moves from nvidia/cuda:12.6.0-cudnn-runtime-ubuntu24.04, from August 2024, to 12.9.2 with current packages.
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 the emSign Root CA - C1 and emSign ECC Root CA - C3 roots. v2.4.0 already removed them from webpki-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 at d9632e7a. This update adds the ORC metadata and type-tree limits.nvidia/cuda 12.6.0 → 12.9.2.DataFusion remains at v55.2.0 and Arrow remains at v59.3.0.
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:
iceberg_s3_endpoint and iceberg_s3_region.iceberg_s3_endpoint to the regional S3 endpoint.s3a://, http://, or https://. Use an s3:// 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 (opens in a new tab) 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.
No new cookbook recipes.
The Spice Cookbook (opens in a new tab) provides recipes to help you get started with Spice.
To upgrade to v2.4.1, use one of the following methods:
CLI:
Homebrew:
Docker:
Pull the spiceai/spiceai:2.4.1 image:
For available tags, see DockerHub (opens in a new tab).
Helm:
AWS Marketplace:
Spice is available in the AWS Marketplace (opens in a new tab).
Full Changelog: https://github.com/spiceai/spiceai/compare/v2.4.0...v2.4.1 (opens in a new tab)