PyO3/pyo3 · error
string contains nul bytes
Error message
string contains nul bytes
What it means
The hidden const helper _cstr_from_utf8_with_nul_checked builds a CStr from a &str at compile time via c_str!. CStr::from_bytes_with_nul fails if the input has interior NUL bytes or doesn't end in exactly one NUL, and const fns can only panic, so it panics with "string contains nul bytes".
Source
Thrown at pyo3-ffi/src/lib.rs:428
/// use core::ffi::CStr;
///
/// const HELLO: &CStr = pyo3_ffi::c_str!("hello");
/// static WORLD: &CStr = pyo3_ffi::c_str!("world");
/// ```
#[macro_export]
macro_rules! c_str {
// TODO: deprecate this now MSRV is above 1.77
($s:expr) => {
$crate::_cstr_from_utf8_with_nul_checked(concat!($s, "\0"))
};
}
/// Private helper for `c_str!` macro.
#[doc(hidden)]
pub const fn _cstr_from_utf8_with_nul_checked(s: &str) -> &core::ffi::CStr {
match core::ffi::CStr::from_bytes_with_nul(s.as_bytes()) {
Ok(cstr) => cstr,
Err(_) => panic!("string contains nul bytes"),
}
}
// Macros for declaring `extern` blocks that link against libpython.
#[path = "impl_/macros.rs"]
#[macro_use]
mod macros;
pub mod compat;
mod impl_;
pub use self::abstract_::*;
#[cfg(not(RustPython))]
pub use self::bltinmodule::*;
pub use self::boolobject::*;
pub use self::bytearrayobject::*;
pub use self::bytesobject::*;
pub use self::ceval::*;View on GitHub (pinned to ac9b6899d3)
Solutions
- Remove interior NUL bytes from the string literal
- Use a single trailing \0 only (which the macro expects)
- Use std::ffi::CStr::from_bytes_with_nul manually with error handling for runtime strings
Example fix
// before
let s = c_str!("foo\0bar\0");
// after
let s = c_str!("foobar\0"); Defensive patterns
Strategy: validation
Validate before calling
fn is_cstr_safe(s: &str) -> bool {
s.as_bytes().iter().filter(|&&b| b == 0).count() == 1 && s.ends_with('\0')
} Prevention
- Never embed interior NUL bytes in string literals passed to c_str!
- Let the macro add the trailing NUL; don't double-terminate
- Prefer CStr::from_bytes_with_nul with match for runtime strings
When it happens
Trigger: Using the c_str! macro (or calling _cstr_from_utf8_with_nul_checked) with a string literal containing an interior \0 or not properly NUL-terminated by the macro.
Common situations: Programmatically generated literals that embed embedded NULs; typos like "foo\0bar" intended as a C identifier; macro misuse with already-escaped strings.
Related errors
- attempted to fetch exception but none was set
- PyObject pointer is null
- `get` may only be specified once
- `set` may only be specified once
- `name` may only be specified once
AI-assisted analysis of PyO3/pyo3@ac9b6899d3 (2026-09-05).
Data as JSON: /api/errors/37ece03901cb7f37.
Report an issue: GitHub.