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

  1. Remove external_streams from MessageBusConfig when building with NautilusKernelBuilder
  2. Switch to LiveNodeBuilder and call with_external_msgbus_factory(...) to get stream ingress
  3. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/fe2b2f1714594b4f. Report an issue: GitHub.