Y2Z/monolith · error
Invalid User-Agent header specified
Error message
Invalid User-Agent header specified
What it means
In `Session::new` (src/session.rs:33), when the caller supplies a `user_agent` in `MonolithOptions`, it is converted to a `HeaderValue` via `HeaderValue::from_str(user_agent).expect("Invalid User-Agent header specified")`. `from_str` rejects any string containing non-visible-ASCII characters (bytes outside 0x20–0x7E, plus DEL/0x7F). If the user-agent string contains such bytes (e.g. non-ASCII text, control characters, embedded newlines), the expect panics during session construction, aborting the whole program before any request is made.
Source
Thrown at src/session.rs:33
pub struct Session {
cache: Option<Cache>,
client: Client,
cookies: Option<Vec<Cookie>>,
pub options: MonolithOptions,
urls: Vec<String>,
}
impl Session {
pub fn new(
cache: Option<Cache>,
cookies: Option<Vec<Cookie>>,
options: MonolithOptions,
) -> Self {
let mut header_map = HeaderMap::new();
if let Some(user_agent) = &options.user_agent {
header_map.insert(
USER_AGENT,
HeaderValue::from_str(user_agent).expect("Invalid User-Agent header specified"),
);
}
let client = Client::builder()
.timeout(Duration::from_secs(if options.timeout > 0 {
options.timeout
} else {
// We have to specify something that eventually makes the program fail
// (prevent it from hanging forever)
600 // 10 minutes in seconds
}))
.danger_accept_invalid_certs(options.insecure)
.default_headers(header_map)
.build()
.expect("Failed to initialize HTTP client");
Session {
cache,
cookies,View on GitHub (pinned to a6fc8d0095)
Solutions
- Pass only ASCII user-agent strings (visible characters, no newlines): e.g. use the standard browser UA format.
- Sanitize/strip the value before constructing options: keep only bytes in 0x20–0x7E and trim whitespace.
- If the goal is a Unicode-looking UA, percent-style or transliterate it — HTTP header values must be visible ASCII.
- In wrapper scripts, validate the UA first: reject or filter it if it fails an ASCII-visible-charset check.
- Patch the code to handle the Result gracefully (fall back to the default UA and warn) instead of expect()-panicking.
Example fix
// before
options.user_agent = Some("Mønolith/1.0 🚀\n".to_string());
// Session::new panics: Invalid User-Agent header specified
// after
let ua: String = "Mønolith/1.0 🚀\n"
.chars()
.filter(|c| (*c as u32) >= 0x20 && (*c as u32) <= 0x7E)
.collect();
options.user_agent = if ua.is_empty() {
None // falls back to default UA
} else {
Some(ua)
}; Defensive patterns
Strategy: validation
Validate before calling
// Validate the user agent before building MonolithOptions
fn is_valid_user_agent(ua: &str) -> bool {
!ua.is_empty()
&& ua
.bytes()
.all(|b| (0x20..=0x7E).contains(&b))
&& !ua.starts_with(' ')
&& !ua.ends_with(' ')
}
// caller
let ua = cli.user_agent.unwrap_or_else(|| DEFAULT_USER_AGENT.to_string());
assert!(is_valid_user_agent(&ua), "user-agent must be visible ASCII");
options.user_agent = Some(ua); Type guard
fn is_safe_header_value(s: &str) -> bool {
s.bytes().all(|b| (0x20..=0x7E).contains(&b))
}
// usage
if let Some(ua) = &options.user_agent {
if !is_safe_header_value(ua) {
eprintln!("ignoring invalid user-agent (must be visible ASCII)");
options.user_agent = None; // fall back to default
}
} Try / catch
match HeaderValue::from_str(user_agent) {
Ok(v) => { header_map.insert(USER_AGENT, v); }
Err(_) => {
eprintln!("warning: invalid user-agent, using default");
header_map.insert(USER_AGENT, HeaderValue::from_static(DEFAULT_USER_AGENT));
}
} Prevention
- Only pass visible-ASCII user-agent strings (no unicode, emoji, or control characters).
- Trim shell variables and strip newlines before assigning --user-agent.
- Read UA values from config with correct encoding (avoid BOM/UTF-16 leakage).
- Sanitize any user-supplied header value with an ASCII-visibility filter before constructing options.
- Favor a graceful fallback to the default UA over expect() when patching the library.
When it happens
Trigger: Calling `Session::new` with `MonolithOptions.user_agent = Some(...)` where the value contains non-ASCII (Unicode) characters, control characters (e.g. \n, \r, \t, \0), or other bytes that violate HTTP header-value visibility rules. Via CLI: `monolith --user-agent "…" <url>` with a UA string pasted containing smart quotes, emoji, CJK text, or a stray newline from a shell variable.
Common situations: Pasting a UA string from a browser devtools export that includes non-ASCII characters; shell variables with trailing control characters or a newline; localized scripts that embed unicode text in the UA; config files read with wrong encoding (UTF-16/BOM bytes leaking in); programmatically constructing options from user input without sanitization.
Related errors
- Time went backwards
- unable to serialize DOM into buffer
- Unable to serialize DOM into buffer
- could not prepare output
- could not write output
AI-assisted analysis of Y2Z/monolith@a6fc8d0095 (2026-09-05).
Data as JSON: /api/errors/81fda8fb7b8ca68f.
Report an issue: GitHub.