nautechsystems/nautilus_trader · error
Failed to parse hex quantity '{s}': {e}
Error message
Failed to parse hex quantity '{s}': {e} What it means
parse_hex_quantity converts a hex quantity string (EVM 'QUANTITY' encoding, e.g. "0x1a") into a u128. It strips an optional 0x prefix and parses with u128::from_str_radix; any parse failure (bad characters, empty string, value exceeding u128) is wrapped in this error including the original string and the inner ParseIntError.
Source
Thrown at crates/adapters/blockchain/src/rpc/types.rs:263
fn deserialize_hex_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
match s.as_str() {
"0x0" => Ok(false),
"0x1" => Ok(true),
_ => Err(serde::de::Error::custom(
"invalid transaction receipt status; expected 0x0 or 0x1",
)),
}
}
fn parse_hex_quantity(s: &str) -> anyhow::Result<u128> {
let stripped = s.strip_prefix("0x").unwrap_or(s);
u128::from_str_radix(stripped, 16)
.map_err(|e| anyhow::anyhow!("Failed to parse hex quantity '{s}': {e}"))
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the '{s}' value in the message; confirm it is a clean hex string (optional 0x prefix, only [0-9a-fA-F]).
- If the source sends decimals or JSON numbers, convert to hex upstream or wrap the field with a tolerant deserializer before it reaches these functions.
- For tag values like 'latest'/'pending', resolve them to a quantity first or use a tag-aware deserializer; this parser only accepts numeric hex.
- If the message shows an overflow-style ParseIntError for a valid hex string, the value exceeds the target width (u64/u8/u128); use the wider deserializer variant.
Example fix
// before (server sends decimal string)
{"blockNumber": "12345"}
// after (EVM hex quantity)
{"blockNumber": "0x3039"} Defensive patterns
Strategy: validation
Validate before calling
fn is_hex_quantity(s: &str) -> bool {
let h = s.strip_prefix("0x").unwrap_or(s);
!h.is_empty() && h.chars().all(|c| c.is_ascii_hexdigit()) && h.chars().count() <= 32
} Try / catch
match parse_hex_quantity(field) {
Ok(v) => { /* use v */ }
Err(e) => { eprintln!("bad quantity field: {e}"); /* treat as null/default */ }
} Prevention
- Ensure your RPC provider returns EVM QUANTITY encoding (0x-prefixed hex) for numeric fields.
- Handle block tags ('latest', 'pending') separately from quantities.
- Use u128-safe deserialization for values that may exceed u64 (e.g. gas, balances).
- Pin and test against the provider's API version to catch format changes early.
When it happens
Trigger: Any deserialize_hex_u64/deserialize_hex_u64_opt/deserialize_hex_u8_opt/deserialize_hex_u128_opt invocation (serde field deserialization of RPC JSON responses) where the field is not a valid hex quantity: contains non-hex characters, is an empty string, uses decimal notation, or the value overflows the target type after conversion.
Common situations: An RPC node returns a decimal string or JSON number instead of a 0x-prefixed hex quantity; a field contains '0x' alone or 'pending'/'latest' tags passed to a quantity field; upstream API changed response format after a version update; value too large for u64/u8 target after a successful u128 parse.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid hex u64: {e}
- Invalid hex u32: {e}
- Invalid receipt log data
- Invalid receipt log topic
- Invalid receipt log hash
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/58d3e22c6990622d.
Report an issue: GitHub.