nautechsystems/nautilus_trader · error
Failed to decode InstrumentDefMsg
Error message
Failed to decode InstrumentDefMsg
What it means
Inside the definition-record iterator, a record was advanced to successfully but `record.get::<InstrumentDefMsg>()` returned None — the record's rtype does not correspond to an InstrumentDefMsg, so it cannot be interpreted as an instrument definition.
Source
Thrown at crates/adapters/databento/src/loader.rs:268
// Loop over skipped records (Ok(None)) so one unsupported class does not
// terminate the stream
Ok(std::iter::from_fn(move || {
loop {
let advance = dbn_stream
.advance()
.map_err(|e| anyhow::anyhow!("Stream advance error: {e}"));
if let Err(e) = advance {
return Some(Err(e));
}
let rec = dbn_stream.get()?;
let result: anyhow::Result<Option<InstrumentAny>> = (|| {
let record = dbn::RecordRef::from(rec);
let msg = record
.get::<InstrumentDefMsg>()
.ok_or_else(|| anyhow::anyhow!("Failed to decode InstrumentDefMsg"))?;
let raw_symbol = rec
.raw_symbol()
.map_err(|e| anyhow::anyhow!("Error decoding `raw_symbol`: {e}"))?;
let symbol = Symbol::from(raw_symbol);
let publisher = rec
.hd
.publisher()
.map_err(|e| anyhow::anyhow!("Invalid `publisher` for record: {e}"))?;
let venue = match publisher {
Publisher::GlbxMdp3Glbx if use_exchange_as_venue => {
let exchange = rec.exchange().map_err(|e| {
anyhow::anyhow!("Missing `exchange` for record: {e}")
})?;
let venue = Venue::from_code(exchange).map_err(|e| {
anyhow::anyhow!("Venue not found for exchange {exchange}: {e}")
})?;View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the file is a `definition` schema export (check via loader.schema_from_file or the Databento download parameters) and point load_instruments at the correct file
- Re-download with schema=definition for the same dataset/range if the wrong file was produced
- Filter/skip non-definition records before this iterator if your pipeline intentionally mixes schemas
Example fix
// before
let instruments = loader.load_instruments(&trades_file_path, ...)?; // wrong schema
// after
assert_eq!(loader.schema_from_file(&path)?, Some("definition".to_string()));
let instruments = loader.load_instruments(&definition_path, ...)?; Defensive patterns
Strategy: validation
Validate before calling
// confirm the file is a definition schema before load_instruments
let schema = loader.schema_from_file(&path)?;
assert_eq!(schema.as_deref(), Some("definition"), "wrong schema for load_instruments"); Try / catch
match loader.load_instruments(&path, true, None) {
Ok(m) => m,
Err(e) if e.to_string().contains("Failed to decode InstrumentDefMsg") => {
anyhow::bail!("{path:?} is not a definition-schema DBN file")
}
other => other,
} Prevention
- Check schema via loader.schema_from_file before loading
- Keep definition files clearly named and separate from data files
- Only point load_instruments at files downloaded with schema=definition
When it happens
Trigger: `read_definition_records` is pointed at a DBN file whose schema is not `definition` (e.g. trades/ohlcv/mbo data), or the file mixes record types so a non-definition record is encountered where an InstrumentDefMsg is required.
Common situations: Passing a data file to load_instruments instead of a definition-schema file, renamed/mislabeled files in a batch download, mixing multiple schemas into one stream.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to decode instrument {instrument_id}: {e}
- Invalid data element not `TradeTick`, was {data:?}
- Invalid data element not `Bar`, was {data:?}
- Failed to get range: {e}
- Missing exchange in record: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5f61523ba2a346ca.
Report an issue: GitHub.