stamparm/maltrail · error

harness config must load

Error message

harness config must load

What it means

Panic raised by `.expect("harness config must load")` when the test harness writes a synthesized config file plus any `options.extra` lines and calls `Config::load`, which returns Err (parse or validation failure). The harness aborts because a malformed test config means the fixture itself is broken.

Solutions

  1. Inspect the extra lines passed via TestOptions and validate each against the keys Config::load accepts
  2. Print the generated config file contents before Config::load to see the exact offending line
  3. Check the parse error returned by Config::load by temporarily replacing expect with a match that panics with the Err payload
  4. Update the extra line to valid `KEY value` syntax recognized by the config parser

Example fix

// before
config_text.push_str("LOG_DiR /tmp/x\n"); // typo key
// after
config_text.push_str("LOG_DIR /tmp/x\n");
Defensive patterns

Strategy: validation

Validate before calling

fn assert_valid_config_lines(extra: &[String], valid_keys: &[&str]) {
    for line in extra {
        let key = line.split_whitespace().next().unwrap_or("");
        assert!(valid_keys.contains(&key), "unknown config key: {line}");
    }
}

Try / catch

let cfg = Config::load(&config_file).unwrap_or_else(|e| panic!("harness config must load: {e:?}"));

Prevention

When it happens

Trigger: `with_options_in` called with `options.extra` lines that are not valid `KEY value` config directives (unknown key, missing value, bad separator, or invalid value type), producing a Config::load failure.

Common situations: Adding a new option line to a test that typos the config key; pasting production config syntax the parser doesn't accept; a Config::load change that newly rejects a previously tolerated key.

Understand the failure class

Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.

Related errors


AI-assisted analysis of stamparm/maltrail@77cfb06d76 (2026-09-13). Data as JSON: /api/errors/fa71d602c9ea099b. Report an issue: GitHub.

Appendix: source

Thrown at sensor/src/testkit.rs:129

             SCAN_WINDOW 30\n\
             USE_HEURISTICS {}\n\
             CHECK_HOST_DOMAINS {}\n\
             CHECK_MISSING_HOST {}\n\
             LOG_DIR {}\n\
             TRAILS_FILE {}\n",
            options.use_heuristics,
            options.check_host_domains,
            options.check_missing_host,
            log_dir.display(),
            trails_file.display()
        );
        for line in &options.extra {
            config_text.push_str(line);
            config_text.push('\n');
        }
        std::fs::write(&config_file, config_text).expect("write config");

        let mut cfg = Config::load(&config_file).expect("harness config must load");
        cfg.root = root.clone();
        let cfg = Arc::new(cfg);

        settings::init(root.clone());
        crate::output::init_error_log(&log_dir, false);

        // An empty whitelist keeps fixture trails from being filtered out; the shipped
        // whitelist is exercised separately in tests/trails.rs. A test that sets USER_WHITELIST
        // gets it honoured, so the precedence tests can pin real whitelist-vs-trail behaviour.
        let whitelist = Arc::new(match cfg.user_whitelist.clone() {
            Some(p) => Whitelist::load(&root, Some(&p)),
            None => Whitelist::default(),
        });

        let db = build_db(trails);
        let store = Arc::new(TrailStore::new(db));
        let view = TrailView::new(store);

View on GitHub (pinned to 77cfb06d76)