stamparm/maltrail · error

worker config must load

Error message

worker config must load

What it means

Panic from `.expect("worker config must load")` when `Config::load` rejects the just-written worker.conf. Since the harness generates the file itself, failure indicates the generated content no longer matches what the config parser accepts.

Solutions

  1. Compare the generated worker.conf keys with what Config::load currently requires and add any missing fields
  2. Print Config::load's Err to see the specific validation failure
  3. Update the format! template in worker_context when config keys change
  4. Verify with a minimal standalone config that Config::load still parses the old syntax

Example fix

// before
"MONITOR_INTERFACE any\nLOG_DIR ...\nTRAILS_FILE ...\n"
// after
"MONITOR_INTERFACE any\nLOG_DIR ...\nTRAILS_FILE ...\n<NEW_REQUIRED_KEY> <value>\n"
Defensive patterns

Strategy: validation

Validate before calling

let required = ["MONITOR_INTERFACE", "LOG_DIR", "TRAILS_FILE"];
for key in required {
    assert!(body.contains(key), "worker.conf missing required key {key}");
}

Try / catch

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

Prevention

When it happens

Trigger: `worker_context()` called after a refactor changed the expected config keys (e.g. MONITOR_INTERFACE, LOG_DIR, TRAILS_FILE renamed or re-validated), or Config::load gained new mandatory fields absent from the generated file.

Common situations: Adding a required config key in Config without updating the testkit's generated worker.conf; strict value validation added for interface names or paths; regression in the config parser itself.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at sensor/src/testkit.rs:326

        format!(
            "MONITOR_INTERFACE any\n\
             CAPTURE_BUFFER 1MB\n\
             PROCESS_COUNT 1\n\
             UPDATE_PERIOD 999999999\n\
             DISABLE_CHECK_SUDO true\n\
             USE_CONDENSED_STORAGE false\n\
             USE_HEURISTICS false\n\
             SENSOR_NAME harness\n\
             LOG_DIR {}\n\
             TRAILS_FILE {}\n",
            log_dir.display(),
            trails_file.display()
        ),
    )
    .expect("write worker config");

    let root = repo_root();
    let mut cfg = Config::load(&config_file).expect("worker config must load");
    cfg.root = root.clone();
    settings::init(root);
    crate::output::init_error_log(&log_dir, false);

    crate::worker::WorkerContext {
        id,
        cfg: Arc::new(cfg),
        whitelist: Arc::new(Whitelist::default()),
        store: Arc::new(TrailStore::new(build_db(&[]))),
        output: Arc::new(OutputConfig {
            sensor_name: "harness".to_string(),
            log_dir,
            trails_file,
            disable_local_log_storage: false,
            local_log_json: false,
            console: false,
            log_server: None,
            log_server_secret: None,

View on GitHub (pinned to 77cfb06d76)