Hey! Hope this is an okay place to ask for some guidance here, I assume there's some dumb mistake I've made somewhere along the line but I haven't had much luck in figuring out what in particular I'm doing wrong, and haven't found a working example for implementing an async HTTP proxy component.
Component is failing to be parsed at TaskCancel:
theo@theo-desktop-black:~/dev/mono/src/apps/wasmtime-wasi-proxy-test-rs$ cargo run -- ../../../target/wasm32-wasip2/release/wasm_test_component.wasm
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.12s
Running `/home/theo/dev/mono/target/debug/wasmtime-wasi-proxy-test-rs ../../../target/wasm32-wasip2/release/wasm_test_component.wasm`
Error: failed to parse WebAssembly module
Caused by:
TaskCancel
With this setup (largely just copying wasmtime_wasi_http docs example but with some added config flags enabled in desparation):
#[tokio::main]
async fn main() -> Result<()> {
let component = std::env::args().nth(1).unwrap();
// Prepare the `Engine` for Wasmtime
let mut config = Config::new();
config.async_support(true);
config.wasm_component_model(true);
config.wasm_component_model_async(true);
let engine = Engine::new(&config)?;
// Compile the component on the command line to machine code
let component = Component::from_file(&engine, &component)?; // <-- fails here
With these features and dependencies in my Cargo.toml:
[package]
name = "wasmtime-wasi-proxy-test-rs"
version = "0.1.0"
edition = "2024"
[dependencies]
anyhow = "1"
hyper = { version = "1", features = ["http1", "server"] }
tokio = { version = "1", features = ["full"] }
wasmtime = { version = "34.0.1", features = ["component-model-async", "async", "component-model"] }
wasmtime-wasi = { version = "34.0.1" }
wasmtime-wasi-http = { version = "34.0.1" }
http-body-util = "0.1"
futures-util = "0.3"
For this component:
mod bindings {
wit_bindgen::generate!({
world: "wasi:http/proxy",
async: true,
generate_all
});
use super::Component;
export!(Component);
}
use bindings::exports::wasi::http::incoming_handler::Guest;
pub use bindings::wasi::http::types::{
Fields, IncomingRequest, OutgoingBody, OutgoingResponse, ResponseOutparam,
};
struct Component;
impl Guest for Component {
async fn handle(_request: IncomingRequest, outparam: ResponseOutparam) {
let hdrs = Fields::new().await;
let resp = OutgoingResponse::new(hdrs).await;
let body = resp.body().await.expect("outgoing response");
ResponseOutparam::set(outparam, Ok(resp)).await;
let out = body.write().await.expect("outgoing stream");
out.blocking_write_and_flush(b"Hello, wasi:http/proxy world!\n".to_vec())
.await
.expect("writing response");
drop(out);
OutgoingBody::finish(body, None).await.unwrap();
}
}
Built and validated as follows:
theo@theo-desktop-black:~/dev/mono/src/apps/wasm-test-component$ cargo build --target wasm32-wasip2 --release
Finished `release` profile [optimized] target(s) in 0.06s
theo@theo-desktop-black:~/dev/mono/src/apps/wasm-test-component$ wasm-tools validate ../../../target/wasm32-wasip2/release/wasm_test_component.wasm --features cm-async --verbose
[2025-07-15T17:05:58Z INFO ] read module in 111.89µs
[2025-07-15T17:05:58Z INFO ] module structure validated in 489.511µs
[2025-07-15T17:05:58Z INFO ] functions validated in 1.307049ms
Anything obviously wrong here? I've checked out wasmtime to start digging through code, but if someone can tell me why I'm a dummy (as I'm currently just pattern matching at this point without any real understanding of what I'm doing) and obviate that search it would be greatly appreciated :eyes:
Hi @Theodore Brockman. The first thing I notice is that the signature of your handle function in the guest component is for wasi:http/incoming-handler@0.2.x, which predates the Component Model async ABI. You'll want to use the 0.3.0-draft version instead, which uses the async ABI.
Here's an example: https://github.com/dicej/hello-wasip3-http. Sorry there's no README.md yet -- I just threw that together yesterday. If you install the latest wasm-tools and then run make in that directory, it should build a component you can run with wasip3-prototyping's version of wasmtime serve. You won't be able to run it on upstream Wasmtime until wasmtime-wasi-http support for p3 is upstreamed from wasip3-prototyping. @Roman Volosatovs is in the process of upstreaming p3 support for both wasmtime-wasi and wasmtime-wasi-http.
@Joel Dice definitely makes sense why it wouldn't be working then :man_facepalming: thanks for the help and info!
Last updated: Dec 06 2025 at 06:05 UTC