Rust 1.98.1 Released: Fixing Critical Vtable Miscompilation in Trait Object Dispatch
Rust 1.98.1 landed today, patching a soundness bug in the previous stable release. The update addresses a miscompilation where rustc could emit null function pointers in trait-object vtables. The result is undefined behavior for safe code.
1.98.0 shipped just two weeks ago on August 20, 2026, bringing LLVM 22 and a slew of stabilized APIs. A point release this fast usually means a critical vulnerability. In this case, it's worse. The bug can turn correctly written Rust into segfaulting binaries without any compiler warnings.
The Bug in Brief
The issue sits in how the compiler handles trait bounds during vtable generation. In some scenarios, rustc decided certain predicates were impossible and skipped emitting the corresponding function pointer. Instead of an error or a placeholder, the compiler wrote a zero.
Safe code dispatching a method through that trait object then jumped to address zero. On Linux and macOS, that produces a SIGSEGV. In release builds, you might see a SIGILL. As the release notes put it, "it is possible for it to be justification for arbitrary effects," which is compiler-speak for any behavior after the crash is technically fair game.
The trigger involves boxed async services and dynamic dispatch with complex associated types. The compiler's trait resolution logic gets confused when dealing with impossible predicates in contexts like BoxService<Input, Output, Error>. Rather than catching the condition at compile time, 1.98.0 silently miscompiled the code.
The Discovery
GlenDC of Plabayo, a European software studio based in Gent, Belgium, found this bug while running their Rama HTTP MITM proxy framework. The reproduction happened on aarch64-apple-darwin under Rust 1.98.0.
The http_mitm_proxy_boring mode would segfault at PC=0x0000000000000000 during CONNECT request handling. The backtrace pointed to an indirect boxed Service call with a zero in the vtable entry at offset 0x18.
"I haven't found a stable rustc bug in 11 years that I used Rust in production," GlenDC wrote in the issue. "I'm really hoping to be wrong here."
The bug hit their CI runners consistently since the 1.98 release. The workaround in Rama involved restructuring BoxService to store the dispatch function pointer separately from the vtable. This bypasses the broken generation path entirely by avoiding trait-object dispatch for that specific method.
Related Miscompilations
This isn't the first time vtable generation has caused headaches for the Rust team. The progression over the last few months shows a clear pattern:
Issue #152735 in February 2026 involved a similar segfault with dyn Future and boxed async closures. Issue #158148 in June produced an ICE when a test file moved out of the crashes directory and exposed the underlying problem. The 1.98.0 bug is the silent variant of the same class. It compiles fine but produces broken binaries. That makes it arguably the most dangerous form of miscompile because you won't know until something crashes in production.
The Rust team has long encouraged beta and nightly usage for a reason. GlenDC's experience proves that even a two-week-old stable release can hide a nasty surprise if your CI isn't already testing against the latest toolchain.
If you upgraded to 1.98.0 recently, update now. Head to rustup and grab the patch. Keep in mind that if your CI is still pinned to 1.97, you might be missing out on testing against this class of issues.
