{"record":{"id":"89eae4c586ff2175","repo":"leptos-rs/leptos","slug":"failed-to-create-headervalue","errorCode":null,"errorMessage":"Failed to create HeaderValue","messagePattern":"Failed to create HeaderValue","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"integrations/actix/src/lib.rs","lineNumber":237,"sourceCode":"/// header contains `text/html` as it does for an ordinary navigation.)\n///\n/// Otherwise, it sets a custom header that indicates to the client that it should redirect,\n/// without actually setting the status code. This means that the client will not follow the\n/// redirect, and can therefore return the value of the server function and then handle\n/// the redirect with client-side routing.\n#[cfg_attr(\n    feature = \"tracing\",\n    tracing::instrument(level = \"trace\", fields(error), skip_all)\n)]\npub fn redirect(path: &str) {\n    if let (Some(req), Some(res)) =\n        (use_context::<Request>(), use_context::<ResponseOptions>())\n    {\n        // insert the Location header in any case\n        res.insert_header(\n            header::LOCATION,\n            header::HeaderValue::from_str(path)\n                .expect(\"Failed to create HeaderValue\"),\n        );\n\n        let accepts_html = req\n            .headers()\n            .get(ACCEPT)\n            .and_then(|v| v.to_str().ok())\n            .map(|v| v.contains(\"text/html\"))\n            .unwrap_or(false);\n        if accepts_html {\n            // if the request accepts text/html, it's a plain form request and needs\n            // to have the 302 code set\n            res.set_status(StatusCode::FOUND);\n        } else {\n            // otherwise, we sent it from the server fn client and actually don't want\n            // to set a real redirect, as this will break the ability to return data\n            // instead, set the REDIRECT_HEADER to indicate that the client should redirect\n            res.insert_header(\n                HeaderName::from_static(REDIRECT_HEADER),","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/leptos-rs/leptos/blob/32d20f6c9d517451d77beb68d88c7716823dac41/integrations/actix/src/lib.rs#L219-L255","documentation":"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.","triggerScenarios":"Calling `leptos_actix::redirect(\"...\")` with a path/URL containing non-ASCII characters (e.g. unencoded CJK or accented characters), newlines, or other control characters.","commonSituations":"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.","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`"],"exampleFix":"// before\nredirect(&format!(\"/users/{}\", user_display_name)); // may contain non-ASCII\n// after\nuse url::form_urlencoded;\nlet encoded: String = form_urlencoded::byte_serialize(user_display_name.as_bytes()).collect();\nredirect(&format!(\"/users/{}\", encoded));","handlingStrategy":"validation","validationCode":"fn is_valid_location(path: &str) -> bool {\n    !path.is_empty()\n        && path.bytes().all(|b| (0x20..=0x7e).contains(&b))\n        && path.starts_with('/')\n}\n\nif !is_valid_location(&target) {\n    // reject or percent-encode before calling redirect\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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()"],"tags":["rust","actix","http-headers","redirect","panic"],"backgroundTag":"invalid-http-header-value","analyzedSha":"32d20f6c9d517451d77beb68d88c7716823dac41","analyzedAt":"2026-09-01T18:55:42.580Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}