nautechsystems/nautilus_trader · error
CStr::from_ptr failed
Error message
CStr::from_ptr failed
What it means
cstr_to_ustr in crates/core/src/ffi/string.rs:72 converts a non-null C string pointer into an interned Ustr. It asserts the pointer is non-null first, then converts the CStr bytes to &str with to_str().expect("CStr::from_ptr failed"), panicking when the bytes are not valid UTF-8. (Note: CStr::from_ptr itself only fails on a null pointer, which the assert already rejects — this expect fires on invalid UTF-8 in the buffer.)
Source
Thrown at crates/core/src/ffi/string.rs:72
// SAFETY: Caller guarantees ptr is borrowed from a valid Python UTF-8 str
Python::attach(|py| unsafe { Bound::from_borrowed_ptr(py, ptr).to_string() })
}
/// Convert a C string pointer into an owned `Ustr`.
///
/// # Safety
///
/// Assumes `ptr` is a valid C string pointer.
///
/// # Panics
///
/// Panics if `ptr` is null.
#[must_use]
pub unsafe fn cstr_to_ustr(ptr: *const c_char) -> Ustr {
assert!(!ptr.is_null(), "`ptr` was NULL");
// SAFETY: Caller guarantees ptr is valid per function contract
let cstr = unsafe { CStr::from_ptr(ptr) };
Ustr::from(cstr.to_str().expect("CStr::from_ptr failed"))
}
/// Convert a C string pointer into a borrowed byte slice.
///
/// # Safety
///
/// - Assumes `ptr` is a valid, null-terminated UTF-8 C string pointer.
/// - The returned slice borrows the underlying allocation; callers must ensure the
/// C buffer outlives every use of the slice.
///
/// # Panics
///
/// Panics if `ptr` is null.
#[must_use]
pub unsafe fn cstr_to_bytes<'a>(ptr: *const c_char) -> &'a [u8] {
assert!(!ptr.is_null(), "`ptr` was NULL");
// SAFETY: Caller guarantees ptr is valid per function contract
let cstr = unsafe { CStr::from_ptr(ptr) };View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the producer encodes all strings as UTF-8 before placing them in the buffer (Python: str.encode('utf-8'); C: use UTF-8 literals/sources).
- Verify buffer lengths so multi-byte characters are not truncated mid-sequence.
- If input encoding is out of your control, use lossy conversion on the producer side or sanitize the string (encode to UTF-8 with replacement) before the FFI call.
- Inspect the raw bytes at the pointer to identify the actual encoding and re-encode it.
Example fix
// before (Python producer)
b"caf\xe9" # Latin-1 encoded, invalid UTF-8
// after
"café".encode("utf-8") # b'caf\xc3\xa9', valid UTF-8 Defensive patterns
Strategy: validation
Validate before calling
# Python producer, before FFI
raw = text.encode("utf-8") # raises UnicodeEncodeError if already mojibake
raw.decode("utf-8") # round-trip: guarantees valid UTF-8 bytes Type guard
def is_utf8(b: bytes) -> bool:
try:
b.decode("utf-8"); return True
except UnicodeDecodeError:
return False Prevention
- Standardize on UTF-8 for every producer writing into FFI buffers.
- Decode vendor data with its true encoding, then re-encode to UTF-8.
- Check buffer lengths so multi-byte characters are never split.
- Test with non-ASCII symbols/labels (e.g. 'café', CJK) to flush out encoding bugs.
When it happens
Trigger: Calling cstr_to_ustr (directly or via optional_cstr_to_ustr, OrderDeniedFfi, OrderRejectedFfi deserialization) with a pointer to bytes that are not UTF-8: Latin-1 or GBK-encoded text, partial multi-byte characters cut by a buffer boundary, or random memory not intended as a string.
Common situations: A C/Python producer encoding strings in a legacy codepage instead of UTF-8; a struct field written as raw bytes without null-termination rules; truncated UTF-8 after a memcpy of the wrong length.
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
- C string contains invalid UTF-8
- Invalid UTF-8 in C string
- Invalid scientific notation exponent '{exponent}': must be a
- invalid `AggressorSide` enum string value, was '{value}'
- invalid `AssetClass` enum string value, was '{value}'
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b2bbd61aad004067.
Report an issue: GitHub.