nautechsystems/nautilus_trader · error
LiveNodeConfig.controller for importable controller '{}' req
Error message
LiveNodeConfig.controller for importable controller '{}' requires the python feature What it means
Importable controllers are loaded via Python (Trader::add_controller_from_importable_config), which requires the crate's `python` feature. Building a live node whose config specifies a controller without that feature compiled in cannot load the controller and fails at build time.
Source
Thrown at crates/live/src/node/builder.rs:599
let runner = AsyncRunner::new();
runner.bind_senders();
let socket_registry = SocketReconnectRegistry::default();
let kernel = NautilusKernel::new_with_dependencies(
self.name.clone(),
self.config.clone(),
NautilusKernelDependencies::default()
.with_clock_factory(self.clock_factory.take())
.with_event_store_factory(self.event_store_factory.take()),
)?;
#[cfg(feature = "python")]
if let Some(controller) = self.config.controller.as_ref() {
Trader::add_controller_from_importable_config(&kernel.trader, controller)?;
}
#[cfg(not(feature = "python"))]
if let Some(controller) = self.config.controller.as_ref() {
anyhow::bail!(
"LiveNodeConfig.controller for importable controller '{}' requires the python feature",
controller.controller_path
);
}
self.install_external_msgbus_factory(&kernel)?;
if let Some(external_egress) = self.external_msgbus_egress.take() {
let config = self.config.msgbus.clone().unwrap_or_default();
nautilus_common::msgbus::get_message_bus()
.borrow_mut()
.set_external_egress_config(external_egress, &config)?;
}
for (name, factory) in self.data_client_factories {
if let Some(config) = self.data_client_configs.remove(&name) {
log::debug!("Creating data client {name}");
View on GitHub (pinned to 18893faf8b)
Solutions
- Rebuild with the `python` feature enabled (e.g. cargo build --features python).
- Remove the controller entry from LiveNodeConfig if Python support is not needed.
- Implement the controller natively in Rust instead of using an importable (Python) controller path.
Example fix
// before (Cargo.toml)
nautilus_live = { version = "..." }
// after
nautilus_live = { version = "...", features = ["python"] } Defensive patterns
Strategy: validation
Validate before calling
if config.controller.is_some() && !cfg!(feature = "python") { /* controller unsupported in this build */ } Try / catch
match node_build_result { Err(e) if e.to_string().contains("requires the python feature") => eprintln!("rebuild with --features python"), other => other? } Prevention
- Align build features between environments that share config files.
- Add a startup assertion that python-dependent features match the binary's features.
- Strip python-specific config entries when deploying Rust-only binaries.
When it happens
Trigger: LiveNodeConfig.controller = Some(...) (with a controller_path) while running a build of nautilus_live compiled without `--features python`, in LiveNodeBuilder::build.
Common situations: Deploying a Rust-only (no-Python) binary with a config copied from a Python setup; Cargo.toml missing the `python` feature; Docker image built without Python support but reusing an existing config file.
Related errors
- CreateActor command for importable actor '{}' is not support
- CreateStrategy command for importable strategy '{}' is not s
- LiveNodeConfig.controller for importable controller '{}' req
- Timedelta not supported for aggregation type: {:?}
- filter_callable {filter_callable:?} requires the Interactive
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/9f05c95e5bfcb90e.
Report an issue: GitHub.