nautechsystems/nautilus_trader · error
JSON string contains interior null bytes
Error message
JSON string contains interior null bytes
What it means
Panic in `string_vec_to_bytes`: after serializing to JSON, `CString::new(json_string).expect("JSON string contains interior null bytes")` aborts if the JSON text contains an interior NUL byte. Since CString cannot represent interior nulls, the library treats such output as a contract violation. For normal string contents serde_json escapes NULs as \u0000, so this is also effectively unreachable for plain strings.
Source
Thrown at crates/core/src/ffi/parsing.rs:85
arr.iter()
.map(|value| {
value
.as_str()
.expect("C string JSON array must contain only strings")
.to_owned()
})
.collect()
}
/// Convert a slice of `String` into a C string pointer (JSON encoded).
///
/// # Panics
///
/// Panics if JSON serialization fails or if the generated string contains interior null bytes.
#[must_use]
pub fn string_vec_to_bytes(strings: &[String]) -> *const c_char {
let json_string = serde_json::to_string(strings).expect("Failed to serialize strings to JSON");
let c_string = CString::new(json_string).expect("JSON string contains interior null bytes");
c_string.into_raw()
}
/// Convert a C bytes pointer into an owned `Option<HashMap<String, Value>>`.
///
/// # Safety
///
/// Assumes `ptr` is a valid C string pointer.
///
/// # Panics
///
/// Panics if `ptr` is not null but contains invalid UTF-8 or JSON.
#[must_use]
pub unsafe fn optional_bytes_to_json(ptr: *const c_char) -> Option<HashMap<String, Value>> {
// SAFETY: A non-null pointer is valid under the caller's contract
unsafe { optional_json_from_cstr(ptr) }
}View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the input strings for raw NUL bytes and strip them at the source if feeding non-standard data
- Do not post-process/replace within the serialized JSON before conversion
- Use the standard serde_json version; rebuild if a patched dependency is present
- If reproducible with plain strings, report it — the expected behavior is escaped \u0000, no panic
Example fix
// before let s = String::from_utf8(vec![b'a', 0, b'b']).unwrap(); // raw interior NUL handled ad-hoc // after let cleaned: String = s.chars().filter(|&c| c != '\0').collect(); let ptr = string_vec_to_bytes(&[cleaned]);
Defensive patterns
Strategy: validation
Validate before calling
assert!(!json_string.contains('\0'), "JSON payload must not contain raw NUL bytes"); Try / catch
let result = std::panic::catch_unwind(|| string_vec_to_bytes(strings));
if result.is_err() { eprintln!("interior NUL in serialized JSON"); } Prevention
- Strip or escape raw NUL bytes from strings at the source
- Do not post-process serialized JSON before conversion
- Keep serde_json standard (it escapes \u0000 automatically)
- Check for memory corruption if this panic ever fires with plain strings
When it happens
Trigger: Calling `string_vec_to_bytes` when the serialized JSON unexpectedly contains a raw interior null byte — realistically only via non-standard serialization output or corrupted string data, not ordinary `Vec<String>` content.
Common situations: Very rare: custom string types or patched serializers emitting raw NULs; post-processing the JSON string before passing it in; memory corruption. Ordinary usage (strings containing '\0') is safe because serde_json escapes them.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- C string contains invalid JSON
- C string JSON must be an array of strings
- C string JSON array must contain only strings
- Failed to serialize strings to JSON
- Invalid scientific notation exponent '{exponent}': must be a
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/972d16b35a755d48.
Report an issue: GitHub.