v1.26.0 Release Notes

Release notes for Fission v1.26.0 — OCI-native package delivery, the Gateway API route provider, streaming responses, and functions as MCP tools.

Upgrade Notes

v1.26.0 is a large feature release and changes several runtime defaults — the router now serves warm traffic from EndpointSlices and accounts concurrency per replica, OCI package delivery becomes the cold-start path when a registry is configured, and streaming responses are no longer bound by the function timeout. None of these require a configuration change to keep working, but review the items below before rolling out, especially if you depend on global concurrency enforcement or on the previous Ingress route flow. The minimum Kubernetes version is unchanged at 1.32.

For the general upgrade steps (CRDs, CLI, Helm chart), see the Upgrade Guide. The behavioral changes specific to v1.26.0 and the action each requires are below.

Router serves warm traffic from EndpointSlices; concurrency is per-replica by default

The router now discovers function pod addresses natively from Kubernetes EndpointSlices instead of asking the executor on every request. Warm traffic no longer makes an executor RPC, so functions stay reachable even while the executor is restarting or unavailable. As part of this, every invoked pool-manager function gets a headless Service automatically (previously these pods were invisible to Kubernetes service discovery), and the router needs new RBAC for endpointslices and services — the chart adds it automatically.

The default concurrency accounting also changes: each router replica now enforces a function’s concurrency limit locally rather than coordinating a global count. On a single-replica router this is identical to before. On a multi-replica router the effective ceiling is the per-function limit times the replica count. If a function requires a strict global limit, set the annotation fission.io/concurrency-enforcement: strict on it to restore global enforcement.

The data plane is on by default (router.endpointSliceCache.mode: "on", executor.functionServices.enabled: true). A one-release escape hatch (router.endpointSliceCache.mode: "off") is available if you need to fall back to executor-driven addressing.

OCI package delivery becomes the cold-start path when a registry is configured

With a package registry configured (packageRegistry.enabled: true plus a repositoryPrefix and push/pull secrets), every successful build now publishes the deployment archive as a digest-pinned OCI image, and functions cold-start by pulling that image instead of downloading a tarball from the storage service. If no registry is configured, nothing changes — packages keep using tarballs through the storage service exactly as before.

fallbackToStorage (default true) keeps a build succeeding by falling back to a tarball if the registry push fails; the package then carries an OCIPublished=False condition. A single package can be kept on the tarball path with the annotation fission.io/package-delivery: tarball.

On Kubernetes 1.33+ you can additionally let the kubelet mount the code image directly as an image volume (executor.enableOCIImageVolume, default true, auto-gated to clusters that support it). See OCI image packages for the full setup, registry-credential, and compatibility detail.

Streaming responses are not bound by the function timeout

Functions can opt into streaming (Server-Sent Events, HTTP chunked transfer, or a WebSocket upgrade) per function. A streaming response is flushed incrementally and is not cut off at functionTimeout; instead it is governed by an idle timeout (default 60s, reset on each chunk) and an optional absolute maxDuration ceiling. Existing functions are unaffected — streaming is off unless you enable it. See Streaming responses.

Ingress route flow is deprecated in favor of the Gateway API

The router can now manage a Gateway API HTTPRoute for an HTTPTrigger, the same way it managed an Ingress for --createingress. The --createingress / IngressConfig path still works but is deprecated, because the Kubernetes Ingress API is frozen. Existing Ingress-based triggers keep working after upgrade and are not auto-converted; migrate them per trigger when you are ready. See Exposing functions with the Gateway API.

Cleanup finalizers are active by default

A fission.io/function-cleanup finalizer (chart-wide finalizerEnabled, default on) makes the executor tear a function’s workloads down before the Function object is collected, closing a long-standing cross-namespace teardown leak. If you ever need to force-delete a Function while the executor is down, clear its finalizers:

kubectl patch function <name> -n <ns> --type=merge -p '{"metadata":{"finalizers":[]}}'

Route conflicts are now deterministic and observable

The router builds its route table incrementally and resolves overlapping triggers with a deterministic precedence (host-qualified before host-less, exact path before prefix, longest prefix, then oldest trigger). A trigger that loses a conflict now surfaces a RouteAdmitted=False condition with reason RouteConflict instead of producing a silently nondeterministic outcome. If you have multiple triggers that overlap on host/path, check the RouteAdmitted condition after upgrading — the winning trigger may differ from the previous, list-order-dependent behavior.

Deprecations/Removals

  • The Ingress route flow (--createingress, IngressConfig) is deprecated in favor of the Gateway API route provider. It still functions; the Kubernetes Ingress API is frozen, so new triggers should use the Gateway API.
  • The event-based WebSocket keepalive mechanism (the fetcher /wsevent endpoints used by the Python socket_tracker.py) is deprecated in favor of the streaming WebSocket path and is targeted for removal in v1.28. The main(ws, clients) programming model is unchanged.
  • Minimum Kubernetes is unchanged at 1.32 (kubeVersion: ">=1.32.0-0").

Highlights

  • OCI-native package delivery. A package’s deployment archive can be an OCI image instead of a zip archive — build a code-only image (FROM scratch), push it to any registry, and reference it with fission package create --oci <ref>. When a package registry is configured, builds publish digest-pinned images automatically and functions cold-start by pulling cached layers instead of downloading and extracting a tarball, with a tarball fallback preserved. On Kubernetes 1.33+ the kubelet can mount the code image directly as an image volume, removing fetch-and-extract from the cold-start path entirely.
  • Gateway API route provider. The router manages a Gateway API HTTPRoute for an HTTPTrigger in attach mode — Fission creates only the route and points it at an operator-owned Gateway, so it works with any conformant implementation (Envoy Gateway, Istio, NGINX Gateway Fabric, …) with minimal RBAC. New fission route flags (--route-provider, --route-host, --route-path, --gateway, --route-annotation) and a spec.routeConfig field configure it.
  • Streaming responses. Functions can stream their response incrementally over Server-Sent Events, HTTP chunked transfer, or a WebSocket upgrade — for LLM token streaming, AI agent runs, chat, and other long-running responses — governed by an idle timeout rather than the function timeout. WebSocket is now first-class for every environment, not just the Python GEVENT environment.
  • Functions as Model Context Protocol (MCP) tools. A function can be advertised as an MCP tool (fission fn create --expose-as-mcp --tool-description …) and discovered and invoked by any LLM agent that speaks MCP, with per-namespace scoping via a signed JWT. A new fission function tools subcommand lists the exposed tools.
  • EndpointSlice-native data plane and a faster router hot path. The router serves warm traffic from EndpointSlices with zero executor RPCs, and a shared HTTP transport fixes connection keep-alive that never actually worked before — together cutting warm-path round-trip time substantially and raising throughput by an order of magnitude under load.
  • Standard Kubernetes conditions on CRDs. Function, Package, HTTPTrigger, and other resources now carry standard status conditions (Ready, BuildSucceeded, RouteAdmitted, …), so kubectl wait --for=condition=Ready function/<name> and fission fn get -o wide (a CONDITIONS column) work, and kubectl describe surfaces why a resource is not ready.

Fixes

  • Incremental router route updates. Canary weight changes and trigger edits no longer rebuild the entire router mux; routes are patched in place through a route table with handler indirection, and conflicts resolve deterministically.
  • Self-healing function workloads. A Deployment or Service deleted out-of-band is now re-created by the executor proactively (targeting MinScale) instead of waiting for the next invocation.
  • Runtime error-noise reduction. Pods use Kubernetes’ native sleep preStop lifecycle action instead of exec /bin/sleep (which failed on shell-less distroless images), and trigger events delivered during the window between trigger creation and route reconciliation are retried instead of dropped on a transient router 404.
  • Endpoint quarantines expire after a TTL so a briefly-unhealthy pod address is retried rather than parked indefinitely.
  • Routine dependency and CI maintenance.
  • Helm chart published as 1.26.0, versioned independently from the app version.

Changelog

What’s Changed

Full Changelog: https://github.com/fission/fission/compare/v1.25.0...v1.26.0

References

Last modified June 13, 2026: Doc changes v1.26.0 (#297) (00c0b14)