nautechsystems/nautilus_trader · error · anyhow::Error
NautilusKernelBuilder cannot consume external message bus st
Error message
NautilusKernelBuilder cannot consume external message bus streams; use LiveNodeBuilder::with_external_msgbus_factory for ingress
What it means
NautilusKernelBuilder::build rejects a MessageBus configuration that declares external_streams, because only LiveNodeBuilder (with an external msgbus factory) can consume streams from an external bus process. The plain kernel builder has no ingress machinery, so the configuration would silently do nothing; it bails instead. This is a static configuration validation.
Source
Thrown at crates/system/src/builder.rs:347
/// Build the [`NautilusKernel`] with the configured settings.
///
/// # Errors
///
/// Returns an error if kernel initialization fails.
pub fn build(self) -> anyhow::Result<NautilusKernel> {
if self.external_msgbus_factory.is_some() && self.external_msgbus_egress.is_some() {
anyhow::bail!("external message bus factory cannot be combined with injected egress");
}
if self.external_msgbus_factory.is_some()
&& self
.msgbus
.as_ref()
.and_then(|config| config.external_streams.as_ref())
.is_some_and(|streams| !streams.is_empty())
{
anyhow::bail!(
"NautilusKernelBuilder cannot consume external message bus streams; \
use LiveNodeBuilder::with_external_msgbus_factory for ingress"
);
}
let config = KernelConfig {
environment: self.environment,
trader_id: self.trader_id,
load_state: self.load_state,
save_state: self.save_state,
shutdown_on_error: self.shutdown_on_error,
logging: self.logging.unwrap_or_default(),
instance_id: self.instance_id,
timeout_connection: self.timeout_connection,
timeout_reconciliation: self.timeout_reconciliation,
timeout_portfolio: self.timeout_portfolio,
timeout_disconnection: self.timeout_disconnection,
delay_post_stop: self.delay_post_stop,View on GitHub (pinned to 18893faf8b)
Solutions
- Remove external_streams from MessageBusConfig when building with NautilusKernelBuilder
- Switch to LiveNodeBuilder and call with_external_msgbus_factory(...) to get stream ingress
- Split the config: keep external_streams only in the live-node configuration path
Example fix
// before
let config = KernelConfig { msgbus: MessageBusConfig { external_streams: Some(vec!["ticks".into()]), ..Default::default() }, .. };
let kernel = NautilusKernelBuilder::new(config).build()?;
// after: live node path
let node = LiveNodeBuilder::new(core_config)
.with_external_msgbus_factory(factory)
.build()?; Defensive patterns
Strategy: validation
Validate before calling
// Guard before building with NautilusKernelBuilder
let uses_streams = kernel_config
.msgbus
.as_ref()
.and_then(|m| m.external_streams.as_ref())
.is_some_and(|s| !s.is_empty());
debug_assert!(!uses_streams, "external_streams require LiveNodeBuilder"); Try / catch
match builder.build() {
Err(e) if e.to_string().contains("cannot consume external message bus streams") => {
// fall back to LiveNodeBuilder::with_external_msgbus_factory
}
other => other?,
} Prevention
- Keep external_streams only in live-node configs
- Validate the config type matches the builder being used
- Use LiveNodeBuilder for any config involving an external message bus
When it happens
Trigger: Building a kernel whose MessageBusConfig.external_streams is a non-empty list while using NautilusKernelBuilder::build() rather than LiveNodeBuilder::with_external_msgbus_factory(...).
Common situations: Porting a live-node config (with Redis/external bus streams) to an offline or backtest kernel builder; enabling external streams in shared config used by both kernel and node creation paths.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- external message bus factory cannot be combined with injecte
- default `PortfolioConfig` should be valid
- Invalid config type for AxExecutionClientFactory. Expected A
- Invalid NodeState value
- Invalid factory address for DEX {name} on chain {chain} for
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fe2b2f1714594b4f.
Report an issue: GitHub.