leptos-rs/leptos · error
Failed to create HeaderValue
Error message
Failed to create HeaderValue
What it means
The actix integration's `redirect()` inserts the `Location` header by converting the target path with `actix_http::header::HeaderValue::from_str(path)` and `.expect()`ing success. `HeaderValue::from_str` fails when the string contains bytes outside visible ASCII range (0x20–0x7E, plus it rejects DEL and control chars), so a redirect target with non-ASCII or control characters panics the server function.
Source
Thrown at integrations/actix/src/lib.rs:237
/// header contains `text/html` as it does for an ordinary navigation.)
///
/// Otherwise, it sets a custom header that indicates to the client that it should redirect,
/// without actually setting the status code. This means that the client will not follow the
/// redirect, and can therefore return the value of the server function and then handle
/// the redirect with client-side routing.
#[cfg_attr(
feature = "tracing",
tracing::instrument(level = "trace", fields(error), skip_all)
)]
pub fn redirect(path: &str) {
if let (Some(req), Some(res)) =
(use_context::<Request>(), use_context::<ResponseOptions>())
{
// insert the Location header in any case
res.insert_header(
header::LOCATION,
header::HeaderValue::from_str(path)
.expect("Failed to create HeaderValue"),
);
let accepts_html = req
.headers()
.get(ACCEPT)
.and_then(|v| v.to_str().ok())
.map(|v| v.contains("text/html"))
.unwrap_or(false);
if accepts_html {
// if the request accepts text/html, it's a plain form request and needs
// to have the 302 code set
res.set_status(StatusCode::FOUND);
} else {
// otherwise, we sent it from the server fn client and actually don't want
// to set a real redirect, as this will break the ability to return data
// instead, set the REDIRECT_HEADER to indicate that the client should redirect
res.insert_header(
HeaderName::from_static(REDIRECT_HEADER),View on GitHub (pinned to 32d20f6c9d)
Solutions
- Percent-encode the path before calling redirect (e.g. `url::Url::parse` + `to_string`, or `utf8_percent_encode(path, NON_ALPHANUMERIC)` / `encode` from `leptos`'s or `form_urlencoded` utilities)
- Validate/sanitize user-supplied redirect targets (allow only ASCII printable, absolute paths) before redirecting
- Return a typed error instead of calling redirect when the target fails `HeaderValue::from_str`-style validation
- Keep Location values as ASCII: encode the path component, keep query strings encoded via `serde_urlencoded`
Example fix
// before
redirect(&format!("/users/{}", user_display_name)); // may contain non-ASCII
// after
use url::form_urlencoded;
let encoded: String = form_urlencoded::byte_serialize(user_display_name.as_bytes()).collect();
redirect(&format!("/users/{}", encoded)); Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_location(path: &str) -> bool {
!path.is_empty()
&& path.bytes().all(|b| (0x20..=0x7e).contains(&b))
&& path.starts_with('/')
}
if !is_valid_location(&target) {
// reject or percent-encode before calling redirect
} Prevention
- Percent-encode all user-derived path segments before building redirect URLs
- Validate redirect targets are ASCII printable absolute paths (also blocks header-injection with \r\n)
- Keep Location targets derived from route constants, not raw display strings or localized text
- Add a unit test that redirects with non-ASCII input never reaches redirect()
When it happens
Trigger: Calling `leptos_actix::redirect("...")` with a path/URL containing non-ASCII characters (e.g. unencoded CJK or accented characters), newlines, or other control characters.
Common situations: Redirecting to a URL built from user input (usernames, search queries, localized slugs) without percent-encoding; logging/teardown paths that embed multiline data; i18n routes where the localized segment wasn't URL-encoded.
Related errors
- Unsupported server function HTTP method: {method:?}
- {}
- Reading from a LocalResource outside Suspense in `ssr` mode
- at {location}, the `sandboxed-arenas` feature is active, but
- failed to spawn future on ThreadPool
AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01).
Data as JSON: /api/errors/89eae4c586ff2175.
Report an issue: GitHub.