nautechsystems/nautilus_trader · error · TransportError
Invalid WebSocket reconnect header value: {e}
Error message
Invalid WebSocket reconnect header value: {e} What it means
The reconnect header update API validates the value with HeaderValue::from_str. Header values must be visible ASCII (no control characters, no non-ASCII/UTF-8 multibyte content, no raw newlines). If the value fails validation, this InvalidInput TransportError is returned and the header is not stored. It is a caller input problem detected before any network I/O.
Source
Thrown at crates/network/src/websocket/client.rs:2282
Self {
inner: Arc::new(RwLock::new(headers)),
}
}
/// Replaces a header used by future automatic reconnect attempts.
///
/// # Errors
///
/// Returns an error if the header name or value is invalid.
pub fn update(&self, name: &str, value: &str) -> Result<(), TransportError> {
let name = HeaderName::from_bytes(name.as_bytes()).map_err(|e| {
TransportError::Io(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("Invalid WebSocket reconnect header name: {e}"),
))
})?;
HeaderValue::from_str(value).map_err(|e| {
TransportError::Io(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("Invalid WebSocket reconnect header value: {e}"),
))
})?;
let name = name.as_str();
let mut headers = self.inner.write();
headers.retain(|(existing, _)| !existing.eq_ignore_ascii_case(name));
headers.push((name.to_string(), value.to_string()));
Ok(())
}
fn snapshot(&self) -> Vec<(String, String)> {
self.inner.read().clone()
}
}
impl Debug for ReconnectHeaders {View on GitHub (pinned to 18893faf8b)
Solutions
- Trim whitespace/newlines from the value before calling update (value.trim())
- Ensure the value is pure visible ASCII; re-encode or fix the source of the credential if it contains other bytes
- Validate the value in your config-loading layer before constructing the client
Example fix
// before
let key = std::fs::read_to_string("key.txt")?; // may contain trailing \n
headers.update("X-Api-Key", &key)?;
// after
let key = std::fs::read_to_string("key.txt")?.trim().to_string();
headers.update("X-Api-Key", &key)?; Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_header_value(v: &str) -> bool {
!v.is_empty() && v.bytes().all(|b| (32..=126).contains(&b) || b == b'\t')
}
let value = raw_value.trim(); // strip file/env newlines Try / catch
match headers.update(name, &value) {
Err(e) if e.to_string().contains("header value") => return Err(InvalidConfig("header value must be visible ASCII".into())),
r => r?,
} Prevention
- Always trim values read from files or environment variables
- Ensure credentials/tokens are pure visible ASCII; re-encode sources containing other bytes
- Reject embedded newlines at your config-validation layer
When it happens
Trigger: Calling update(name, value) where value contains characters outside visible ASCII range, control characters, or embedded newlines — e.g. tokens read from files with trailing newline, or credentials with unicode characters.
Common situations: Reading API keys from files/env without trimming (embedded \n or \r); non-ASCII secrets or unicode quotes pasted into config; logging/formatted values containing control characters.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid WebSocket reconnect header name: {e}
- Not a subscription channel: {kind}
- {field} must be non-negative, was {value}
- order price must be in (0, 1)
- invalid order quantity
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e5c79502e994a0fc.
Report an issue: GitHub.