diem/diem · critical

Failed to load node config

Error message

Failed to load node config

What it means

NodeConfig::load deserializes the node's TOML configuration file into a NodeConfig. The .expect("Failed to load node config") panics when the file cannot be read or fails to deserialize against the NodeConfig schema. The node refuses to start because almost every subsystem depends on valid config values.

Source

Thrown at diem-node/src/main.rs:64

static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;

fn main() {
    let args = Args::from_args();

    if args.test {
        println!("Entering test mode, this should never be used in production!");
        let rng = args
            .seed
            .map(StdRng::from_seed)
            .unwrap_or_else(StdRng::from_entropy);
        let publishing_option = if args.open_publishing {
            Some(VMPublishingOption::open())
        } else {
            None
        };
        diem_node::load_test_environment(args.config, args.random_ports, publishing_option, rng);
    } else {
        let config = NodeConfig::load(args.config.unwrap()).expect("Failed to load node config");
        println!("Using node config {:?}", &config);
        diem_node::start(&config, None);
    };
}

View on GitHub (pinned to fc4714a8ea)

Solutions

  1. Verify the config file path exists and is readable by the process user.
  2. Validate the TOML parses (e.g. with any TOML linter) and fix syntax/type errors.
  3. Regenerate the config with the matching diem-node version (config builder / config-gen) instead of reusing an old file.
  4. Run with an out-of-tree test setup (`--test`) only for local testing, never in production.

Example fix

// before
diem-node --config /etc/diem/node.toml   # file missing
// after
diem-node --config /etc/diem/node.yaml   # correct, existing NodeConfig file path
Defensive patterns

Strategy: validation

Validate before calling

let path = args.config.unwrap_or_default();
if !std::path::Path::new(&path).is_file() {
    panic!("node config file not found: {}", path);
}
// Optionally pre-parse TOML to surface schema errors before NodeConfig::load
let raw = std::fs::read_to_string(&path)?;
toml::from_str::<toml::Value>(&raw)?;

Type guard

fn config_exists(p: &str) -> bool { std::path::Path::new(p).is_file() }

Try / catch

match NodeConfig::load(path.clone()) {
    Ok(config) => diem_node::start(&config, None),
    Err(e) => eprintln!("Failed to load node config {:?}: {}", path, e),
}

Prevention

When it happens

Trigger: Running `diem-node` (without --test) with a path that does not exist, is unreadable (permissions), contains invalid TOML syntax, or has fields with wrong types/unknown keys that fail NodeConfig deserialization.

Common situations: Operator passes a typo'd or relative --config path from the wrong working directory; a config generated by an older Diem version lacks newly required fields; hand-edited TOML introduces a syntax or type error.

Related errors


AI-assisted analysis of diem/diem@fc4714a8ea (2026-09-04). Data as JSON: /api/errors/6a8fb3f922472f28. Report an issue: GitHub.