stamparm/maltrail · error

create harness dir

Error message

create harness dir

What it means

The test harness with_options_in() creates a unique temp directory per harness instance (maltrail-harness-{pid}-{id}) via std::fs::create_dir_all and panics with "create harness dir" on failure. Because the stale directory is removed first, failure generally means a filesystem/permission/environment problem, not a leftover directory.

Solutions

  1. Check TMPDIR/std::env::temp_dir() resolves to a writable existing directory
  2. Free disk space on the temp filesystem if it is full
  3. Remove stale maltrail-harness-* directories owned by other UIDs from the temp dir
  4. Include the io::Error and dir path in the panic message for diagnosis

Example fix

// before
std::fs::create_dir_all(&dir).expect("create harness dir");
// after
std::fs::create_dir_all(&dir)
    .unwrap_or_else(|e| panic!("create harness dir {}: {e}", dir.display()));
Defensive patterns

Strategy: validation

Validate before calling

let td = std::env::temp_dir(); assert!(td.is_dir() && td.metadata().map(|m| m.permissions().writable()).unwrap_or(false), "temp dir {} not writable", td.display());

Type guard

fn temp_dir_writable() -> bool { let td = std::env::temp_dir(); td.is_dir() && std::fs::create_dir_all(td.join(".wprobe")).is_ok() && std::fs::remove_dir(td.join(".wprobe")).is_ok() }

Try / catch

std::fs::create_dir_all(&dir).unwrap_or_else(|e| panic!("create harness dir {}: {e}", dir.display()));

Prevention

When it happens

Trigger: Calling Harness::with_options_in() when std::env::temp_dir() is unwritable, full, or on a read-only filesystem, so create_dir_all(dir) returns Err after the remove_dir_all cleanup.

Common situations: TMPDIR pointing to a non-existent or unwritable path; disk-full /tmp in CI; running tests as a user without write permission on the temp dir; stale harness dirs owned by another user (pid collision after container restart).

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


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

Appendix: source

Thrown at sensor/src/testkit.rs:91

    /// A harness whose events go to a CALLER-CHOSEN log directory, so several harnesses can be
    /// pointed at one directory and made to race on the daily log file.
    pub fn with_log_dir(log_dir: &std::path::Path, trails: &[(&str, &str, &str)]) -> Harness {
        Harness::with_options_in(trails, HarnessOptions::quiet(), Some(log_dir))
    }

    pub fn with_options(trails: &[(&str, &str, &str)], options: HarnessOptions) -> Harness {
        Harness::with_options_in(trails, options, None)
    }

    fn with_options_in(
        trails: &[(&str, &str, &str)],
        options: HarnessOptions,
        shared_log_dir: Option<&std::path::Path>,
    ) -> Harness {
        let id = COUNTER.fetch_add(1, Ordering::Relaxed);
        let dir = std::env::temp_dir().join(format!("maltrail-harness-{}-{}", std::process::id(), id));
        let _ = std::fs::remove_dir_all(&dir);
        std::fs::create_dir_all(&dir).expect("create harness dir");
        let log_dir = match shared_log_dir {
            Some(p) => p.to_path_buf(),
            None => dir.join("logs"),
        };
        std::fs::create_dir_all(&log_dir).expect("create log dir");

        let trails_file = dir.join("trails.csv");
        std::fs::write(&trails_file, "").expect("write trails");

        let root = repo_root();
        let config_file = dir.join("harness.conf");
        let mut config_text = 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\

View on GitHub (pinned to 77cfb06d76)