DioxusLabs/dioxus · error

HTTP handshake failed

Error message

HTTP handshake failed: {e}

What it means

Raised in send_with_retry (called from proxy_to) when the TCP connection to the backend succeeded but the hyper http1::handshake over that stream failed. This means the peer accepted the socket yet did not complete a valid HTTP/1.1 exchange (not an HTTP server, TLS mismatch, or connection reset) — the error is mapped through the proxy's handle_error callback into an HTTP error response.

Solutions

  1. The HTTP handshake with the proxy backend failed. Verify the backend URL, protocol, and TLS configuration.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at packages/cli/src/serve/proxy.rs:59 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


AI-assisted analysis of DioxusLabs/dioxus@fda3dc9c2b (2026-08-23). Data as JSON: /api/errors/b9f68cc122c6128b. Report an issue: GitHub.

Appendix: source

Thrown at packages/cli/src/serve/proxy.rs:59

                if start.elapsed() >= max_wait {
                    return Err(handle_error(anyhow::anyhow!(
                        "Backend not ready after {max_wait:?}: {e}"
                    )));
                }
                tracing::debug!("Backend not ready, retrying in {backoff:?}...");
                tokio::time::sleep(backoff).await;
                backoff = (backoff * 2).min(std::time::Duration::from_secs(2));
            }
        }
    };

    // Wrap the TCP stream for hyper
    let io = TokioIo::new(stream);

    // Perform HTTP/1.1 handshake on the same connection
    let (mut sender, conn) = http1::handshake(io)
        .await
        .map_err(|e| handle_error(anyhow::anyhow!("HTTP handshake failed: {e}")))?;

    // Spawn connection driver to keep it alive
    tokio::spawn(async move {
        if let Err(e) = conn.await {
            tracing::debug!("Connection closed: {e}");
        }
    });

    // Send request through the established connection (streaming body)
    sender
        .send_request(req)
        .await
        .map_err(|e| handle_error(anyhow::anyhow!("Request failed: {e}")))
}

/// Add routes to the router handling the specified proxy config.
///
/// We will proxy requests directed at either:

View on GitHub (pinned to fda3dc9c2b)