nautechsystems/nautilus_trader · error
Invalid config type for BlockchainDataClientFactory. Expecte
Error message
Invalid config type for BlockchainDataClientFactory. Expected `BlockchainDataClientConfig`, was {config:?} What it means
BlockchainDataClientFactory.create downcasts the passed config object to BlockchainDataClientConfig. This error fires when the config object supplied to the factory is of a different concrete type, so the downcast_ref returns None.
Source
Thrown at crates/adapters/blockchain/src/factories.rs:86
impl Default for BlockchainDataClientFactory {
fn default() -> Self {
Self::new()
}
}
impl DataClientFactory for BlockchainDataClientFactory {
fn create(
&self,
name: &str,
config: &dyn ClientConfig,
_cache: CacheView,
_clock: Rc<RefCell<dyn Clock>>,
) -> anyhow::Result<Box<dyn DataClient>> {
let blockchain_config = config
.as_any()
.downcast_ref::<BlockchainDataClientConfig>()
.ok_or_else(|| {
anyhow::anyhow!(
"Invalid config type for BlockchainDataClientFactory. Expected `BlockchainDataClientConfig`, was {config:?}"
)
})?;
let client = BlockchainDataClient::new(ClientId::from(name), blockchain_config.clone());
Ok(Box::new(client))
}
fn name(&self) -> &'static str {
BLOCKCHAIN
}
fn config_type(&self) -> &'static str {
"BlockchainDataClientConfig"
}
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Pass a BlockchainDataClientConfig instance to the data client factory
- Check the factory registration: data client factories must be paired with data client configs
- Print the config's concrete type and compare with BlockchainDataClientConfig
- Fix the config deserialization so it produces BlockchainDataClientConfig
Example fix
// before
factory.create(name, &other_config, ...) // other_config: BlockchainExecutionClientConfig
// after
let config = BlockchainDataClientConfig { /* ... */ };
factory.create(name, &config, ...) Defensive patterns
Strategy: type-guard
Validate before calling
if config.as_any().downcast_ref::<BlockchainDataClientConfig>().is_none() {
panic!("data client factory requires BlockchainDataClientConfig, got {:?}", config);
} Type guard
fn is_data_client_config(config: &dyn ClientConfig) -> bool {
config.as_any().downcast_ref::<BlockchainDataClientConfig>().is_some()
} Try / catch
// wrap factory.create in error context
let client = factory.create(name, &config, ...)
.map_err(|e| anyhow::anyhow!("data client factory rejected config: {e:#}"))?; Prevention
- Pair each factory registration with its matching config type in a single construction site
- Name factory/config pairs consistently (DataClientFactory <-> DataClientConfig)
- Add a startup smoke test that builds every registered client with its config
When it happens
Trigger: Calling BlockchainDataClientFactory.create (or the node factory registration path) with a config that is not a BlockchainDataClientConfig instance.
Common situations: Wiring the factory in a node builder but registering a generic/other client's config (e.g. an execution client config or a hand-rolled config struct); copy-pasted factory registration with the wrong config type; config deserialized into the wrong type.
Related errors
- Invalid config type for BlockchainExecutionClientFactory. Ex
- Invalid config type for DatabentoDataClientFactory. Expected
- Invalid config type for DeribitDataClientFactory. Expected D
- Invalid config type for DeribitExecutionClientFactory. Expec
- Invalid config type for AxExecutionClientFactory. Expected A
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/4f876674c52fa109.
Report an issue: GitHub.