stamparm/maltrail · error

create log dir

Error message

create log dir

What it means

Right after creating the harness directory, with_options_in() creates the logs subdirectory (or uses the shared log dir) with std::fs::create_dir_all and panics with "create log dir" on failure. When a shared_log_dir is supplied, that pre-existing path must be writable; otherwise the fresh harness dir's logs/ must be creatable.

Solutions

  1. Verify the shared_log_dir path exists, is a directory, and is writable before calling with_options_in
  2. Pass None to let the harness manage its own logs subdirectory if the shared path is unreliable
  3. Check disk space and permissions on the temp filesystem
  4. Include the log_dir path and io::Error in the panic message

Example fix

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

Strategy: validation

Validate before calling

if let Some(p) = shared_log_dir { assert!(p.is_dir() && p.metadata().map(|m| m.permissions().writable()).unwrap_or(false), "shared_log_dir {} not a writable dir", p.display()); }

Type guard

fn usable_log_dir(p: &std::path::Path) -> bool { p.is_dir() && p.metadata().map(|m| m.permissions().writable()).unwrap_or(false) }

Try / catch

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

Prevention

When it happens

Trigger: Calling Harness::with_options_in() where dir.join("logs") cannot be created (filesystem error), or the provided shared_log_dir path does not exist and cannot be created (bad path, permissions, disk full).

Common situations: Passing a shared_log_dir pointing at a file instead of a directory or an unwritable path; read-only test volume; race where another process deleted the shared log dir between calls.

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/7f27fdce76be32e2. Report an issue: GitHub.

Appendix: source

Thrown at sensor/src/testkit.rs:96

    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\
             SENSOR_NAME harness\n\
             SCAN_WINDOW 30\n\
             USE_HEURISTICS {}\n\
             CHECK_HOST_DOMAINS {}\n\
             CHECK_MISSING_HOST {}\n\

View on GitHub (pinned to 77cfb06d76)