On this page · 11 sections
- Key changes at a glance
- Default behaviour changes in 50.0.0
- Embedder API changes
- Component-model-async changes
- Serve command, CLI, and wasi:http updates
- Compiler and memory changes in 50.0.0
- Fixes in 50.0.0 with user-visible effects
- Security and panic fixes in 49.0.3
- Build requirements and tooling
- Upgrade checklist
- Sources
TL;DR
Wasmtime 50.0.0 changes several defaults in the CLI and Winch, adds new embedder APIs, and updates component-model-async to the latest specification. Teams that run the wasmtime CLI, embed Wasmtime through its Rust or C APIs, or use wasi:http should review these notes. The separate 49.0.3 release lists a set of fixes tagged with GitHub Security Advisory identifiers.
Two release notes need to be read together. The Wasmtime 50.0.0 release notes list behaviour changes that can break scripts or embedding code without any compile-time warning, along with new APIs and updates to the component model. The Wasmtime 49.0.3 release notes list panic, sandbox, and resource-limit fixes, each with a GitHub Security Advisory identifier. This article covers what each release states, who should act on it, and the order in which to check your setup.
Key changes at a glance #
The table below lists the changes that most directly affect upgrade work. Each row names the release that lists the change. Items not in the table are covered in the sections that follow.
| Change | Who is affected | Action |
|---|---|---|
| The wasmtime CLI no longer enables WASIp0 (wasi_unstable) by default; it can be enabled with -Spreview0 (v50.0.0) | CLI users running modules that import wasi_unstable | Check module imports and add -Spreview0 where needed |
| Winch no longer enables the GC types, exceptions, or tail-call proposals by default (v50.0.0) | Winch users who relied on these defaults | Enable the proposals explicitly if your workload needs them |
| Epoch deadline and call-hook callbacks receive a StoreHookState instead of a StoreContextMut (v50.0.0) | Embedders that implement these callbacks | Update callback signatures and the state types they access |
| Accessor::spawn takes an async closure instead of an AccessorTask (v50.0.0) | Embedders calling Accessor::spawn | Rewrite call sites to pass an async closure |
| The CLI rejects zero for the --http-outgoing-body-* options (v50.0.0) | Users of the CLI and scripts that pass zero to these options | Replace zero values in scripts and configuration |
| Wasmtime requires Rust 1.97.0 to compile (v50.0.0) | Anyone building Wasmtime from source | Update the Rust toolchain before building |
| Component-model-async updated to the latest specification (v50.0.0) | Embedders using component-model-async | Review cancellation and handle-drop behaviour in guest and host code |
| Fixes for panics, a filesystem sandbox escape, and HTTP request handling tagged with advisory identifiers (v49.0.3) | Embedders and operators running the affected code paths | Compare your exposure with the advisory list and deploy the fixed release |
Default behaviour changes in 50.0.0 #
The clearest breaking-style changes in the 50.0.0 notes are defaults. The notes state that the wasmtime CLI "no longer enables WASIp0 (wasi_unstable) by default" and that it "can be enabled with -Spreview0." A module that imports the older wasi_unstable interface will need that flag after this release. The notes do not say what error a user will see without it, so verify this with a test module in your own environment rather than relying on an assumption about the failure mode.
Winch, the baseline compiler, also changed its defaults. The 50.0.0 notes say Winch "no longer enables the GC types, exceptions, or tail-call proposals by default as support for these is not yet Tier 1." The reason given in the notes is the support tier. If your build or test harness depends on any of these proposals with Winch, you need to enable them explicitly. The same notes also say that Winch now supports tail calls on x86_64 and AArch64, which is a separate change in the same release, so the two entries should not be read as a single statement about tail calls.
The CLI also gained a stricter validation rule. The notes say the CLI "now rejects zero for the --http-outgoing-body-* options." Any script that passes zero to those options will now stop with an error. The 50.0.0 notes also state that wasmtime run now honors the same --http-outgoing-body-* options, which means behaviour for the run subcommand changed in the same release. Review both entries together when you update command lines.
Embedder API changes #
Embedders see the most source-level changes. The notes say that "Changed Epoch deadline and call-hook callbacks now receive a StoreHookState instead of a StoreContextMut, which only allows access to the T in a Store<T>." The notes describe the new type as one that gives access to a narrower set of things than before. If your callbacks read data from the store, check which operations the new state type supports, and update each callback to match the new signature.
The second API change concerns async host code. The notes state that "Accessor::spawn now takes an async closure instead of an AccessorTask." This is a direct signature change. Any code that constructs an AccessorTask to pass to Accessor::spawn must be rewritten to pass a closure. The notes do not give a migration example, so use the compiler errors as your guide to the new shape of each call site.
The 50.0.0 release also adds new methods. The notes list the following:
- Store::gc_heap_grow, which can be used to manually grow the GC heap of a store.
- ResourceAny::resource_drop_concurrent, which can drop a guest resource with only an Accessor.
- Engine::release_idle_pool_memory, which can release memory kept resident by the pooling allocator for idle slots.
- An off-by-default task-group-hook feature, which lets embedders associate guest-to-host calls with their corresponding host-to-guest calls when using component-model-async.
Because these are additions, existing code does not need to change to use them. Adopt them only where your embedding code needs manual GC heap growth, concurrent resource drops, pooling memory release, or call association for tracing. The notes do not state performance results for any of these methods, so do not treat them as tuning recommendations without your own measurements.
The Wasmtime CLI and C API can now enable the component model's canonical names and accessors features.
That line from the 50.0.0 notes describes a configuration option, not a default. If you use the C API, check whether your build should opt in.
Component-model-async changes #
The 50.0.0 notes report that component-model-async "has been updated to the latest specification." The notes list four specific changes. The cancellable immediate was removed from intrinsics. The semantics of subtask.cancel were refined. task.cancel now traps before the cancel event is delivered. Use of stream or future handles after the other end has been dropped now traps.
The last two items are the ones most likely to affect existing guests and hosts. A guest or host that calls task.cancel or uses a stream or future handle after the peer has gone will now trap, instead of continuing. The notes do not describe which code paths were previously tolerant, so audit your own stream and future handling and confirm that cleanup happens before the peer is dropped.
The release also contains changes to scheduling and calls. The notes say that component-model-async "now periodically yields during concurrent work to avoid starving other host tasks." The notes also say that the performance of async guest-to-host calls "has been improved by lazily creating host tasks," and that sync-to-sync adapters "no longer need to call {enter,exit}-sync-call in many cases." The notes state these as improvements, but they do not give benchmark numbers or name a workload. Treat them as behaviour changes to observe in your own traces rather than as measured gains.
The notes also state that "Recursive run_concurrent is now allowed for disparate stores." This is a relaxation of a previous restriction in the notes' description. Where code relied on the restriction for correctness, check that the new behaviour is what you want.
Serve command, CLI, and wasi:http updates #
The wasmtime serve command received several additions in 50.0.0. The notes say it can now inherit listening sockets from a service manager, for example systemd socket units, through a new --systemd-listenfd option. It can serve on Unix sockets. It can also exit automatically when idle through a new --idle-process-timeout option. These options are useful for operators who run the server under a process supervisor, but the notes do not describe default values, so set them explicitly in your service definitions.
The same release states that graceful shutdown of wasmtime serve "has been fixed." If you have workarounds for shutdown behaviour, test them against 50.0.0 before removing them.
For wasi:http, the 50.0.0 notes list several changes. The notes say that wasi:http "now always accepts an empty path-with-query." They say that default wasi:http hooks "now classify connection and TLS errors in more detail." The notes also list three fixes that appear after the main list: wasi-http p3 now correctly enforces content-length for response bodies, wasi-http p3 applies the forbidden header check to trailers, and wasi-http now prohibits duplicate content-length headers. If your code parses HTTP responses or inspects error categories, these changes may alter what you observe.
The wasmtime-wasi and wasmtime-wasi-http crates also gained support for "named imports," which the notes describe as the implements field of the component model. The notes do not describe a migration path, so this is an addition to adopt when you need it.
Compiler and memory changes in 50.0.0 #
The compiler section of the 50.0.0 notes contains changes that do not require code edits but may change resource use. The notes say that Wasmtime "now drops cached compiler contexts between compiling modules/components, reducing sustained memory usage." The notes describe the effect on sustained memory only. They do not give figures for any workload, so use your own measurements before drawing conclusions.
Cranelift's alias analysis is described as "faster and more precise," and the notes say that GC struct fields, array elements, and GC header fields now each have their own alias regions. The notes also say that Wasmtime "now uses bulk libunwind section registration when available." These are internal changes. They matter most if you profile compile time or inspect generated code.
The pooling allocator also changed. The notes say it "now scans further than a fixed set of region and additionally correctly resets pages that have been paged out." If you run with the pooling allocator, include it in your regression tests, particularly tests that cycle instances.
Fuel accounting changed in two ways. The notes say that "Fuel is now charged for more host allocations made with Val," and that fuel is now saved and restored correctly around call_ref and exception catches in Cranelift. If you use fuel to bound execution, recheck your limits because the amount charged per operation can differ.
Fixes in 50.0.0 with user-visible effects #
The 50.0.0 notes list several fixes that change runtime behaviour. The notes say that Store::set_epoch_deadline "no longer overflows with very large deltas." They say the JIT code is "now made coherent with the instruction cache correctly on AArch64." They say native stack-walking on macOS arm64 "has been fixed." They also say the check-write budget "is now enforced in wasi:http outgoing bodies and some wasi:io output streams." That last item may make a previously accepted write fail, so test applications that stream large bodies.
The notes also describe a fix to resource handling. Converting a borrowed Resource<T> or ResourceDynamic created with new_borrow into a ResourceAny outside a component call "no longer panics." The notes state that the borrow is now lowered into the guest when the call happens, and that ResourceAny::resource_drop "is no longer required for such borrows." If your code calls resource_drop on these borrows, review it against the new rule.
The wasi:filesystem entries list several fixes: set-times on directory descriptors, stat of symlinks with trailing slashes, the stat fast path, datetime overflow, and directory entry file types on filesystems without d_type. If your application depends on any of these, test them on your target filesystems.
Security and panic fixes in 49.0.3 #
The Wasmtime 49.0.3 release notes list the following fixed items, each tagged with an advisory identifier. The notes list them as fixes in that release. Below, each item is paraphrased from the notes:
- Out-of-bounds zero-length stream writes can panic (GHSA-93g3-36p8-x2gc).
- A host panic occurs when a component call_async is cancelled under some conditions (GHSA-3r89-v5mq-j5xf).
- An erroneous call-to-host from a guest realloc call can panic (GHSA-7v24-42x9-pxf7).
- Yielding in a component start function can lead to a host panic (GHSA-5hhx-4wrr-3j9g).
- A panic occurs when invoking an async-lifted function via call (GHSA-m6w2-jwq2-cv2c).
- A panic occurs when pending calls run after a trap (GHSA-hmwq-g22x-qjw5).
- A stack overflow occurs when dropping a long chain of recursive types (GHSA-wjc8-633q-pwxr).
- Wasmtime may not properly enforce the async-entrypoint requirement (GHSA-vcg5-q8m5-8379).
- A panic occurs when viewing a component model stream or future as the wrong type (GHSA-63h4-6cx9-pjfj).
- Component-model handle tables are capped only per instance and charged to no limit (GHSA-q554-3cjc-rx7p).
- Exception tags can cause host data structures to be unaligned (GHSA-p79w-pv2r-29qp).
- A filesystem sandbox escape exists when renaming symlinks with trailing slashes (GHSA-m9f7-9w4p-gv38).
- An overlapping string transcode in a fused adapter can panic (GHSA-54p9-vhhq-8f7q).
- Guests can send absolute-form HTTP requests to different hosts (GHSA-5qpp-g3j2-8frx).
- A wasi-http request with a long URL before a query parameter crashes the host (GHSA-w36r-2hch-9xp9).
The notes do not describe exploit conditions or affected version ranges beyond the release in which each fix is listed. Use the advisory identifiers to find the full details and to determine whether your deployment is affected. The filesystem sandbox escape and the guest-initiated HTTP request entry are the items most directly tied to isolation boundaries, so prioritise them in your review.
The 49.0.3 notes are short and list only fixes, so they contain no default changes or API changes. Apply them alongside the 50.0.0 review rather than instead of it, because the two releases describe different sets of changes.
Warning
The 49.0.3 notes name advisories without stating which earlier versions are affected. Confirm exposure against each GHSA entry before deciding how urgently to deploy.
Build requirements and tooling #
The 50.0.0 notes state that "Wasmtime now requires Rust 1.97.0 to compile." If your CI pins an older toolchain to build Wasmtime from source, update that pin. The notes also say Cranelift now allows returns via xmm1 with WindowsFastCall for extern "Rust," and that cranelift-object now returns an error, instead of panicking, for data objects declared with different TLS values. Both entries matter only if you build or use these crates directly.
The Wasmtime CLI and C API can now enable the component model's canonical names and accessors features. The notes also state that the debugger now exposes shared memories to gdbstub, and that wasmtime explore now supports components and has resizable panes. These are additions for developers who use those tools.
Upgrade checklist #
- Read the Wasmtime 50.0.0 release notes and the Wasmtime 49.0.3 release notes in full before changing any dependency version.
- Map each GHSA identifier in the 49.0.3 notes to your deployments, starting with the sandbox escape and guest-initiated HTTP request entries, and record which ones apply to you.
- Search your scripts and configuration for wasi_unstable imports and for the --http-outgoing-body-* options, and update them for the -Spreview0 flag and the zero-value rejection.
- If you use Winch, list any dependency on the GC types, exceptions, or tail-call proposals and enable them explicitly.
- Update every Epoch deadline and call-hook callback to the StoreHookState signature.
- Rewrite each Accessor::spawn call so it passes an async closure.
- Audit component-model-async code for task.cancel calls and for stream or future handles used after the peer has been dropped, since these now trap.
- Check resource-drop logic for borrows created with new_borrow, since the notes say ResourceAny::resource_drop is no longer required for them.
- Update the Rust toolchain to 1.97.0 in any CI job that builds Wasmtime from source.
- Run your regression suite, including wasi:http streaming tests, pooling allocator tests, and fuel-limit tests, against the new release.
- Measure memory use and compile behaviour on your own workloads, since the notes give no figures for these changes.
Key takeaways
Wasmtime 50.0.0 contains the changes that most affect upgrades: CLI and Winch defaults, the StoreHookState and Accessor::spawn signatures, component-model-async behaviour, and a Rust 1.97.0 build requirement. Wasmtime 49.0.3 lists fixes tagged with advisory identifiers, several of which concern panics and sandbox boundaries. Review both release notes, map the advisories to your deployments, and test the changed behaviours before rollout.
Sources
- Release v50.0.0: Release Wasmtime 50.0.0 (#14877) · bytecodealliance/wasmtime · GitHub github.com · Oct 20, 2026
- Release v49.0.3: Release Wasmtime 49.0.3 (#14725) · bytecodealliance/wasmtime · GitHub github.com · Oct 14, 2026
Edited and approved by Jarosław Krzemiński. Spotted a mistake? Report a correction or read the corrections policy.




Comments