zeroclaw-labs/zeroclaw · error · std::io::Error

Landlock is only supported on Linux

Error message

Landlock is only supported on Linux

What it means

with_workspace is the workspace-scoped constructor, and on stub builds (non-Linux target, or Linux without the `sandbox-landlock` feature — the negative cfg block at landlock.rs:311) it returns io::ErrorKind::Unsupported before ever touching the workspace path, which the stub deliberately ignores (_workspace_dir). Note the message here says only "Landlock is only supported on Linux" even though a feature-less Linux build also lands in this stub, unlike new()'s message which names the feature. The real implementation, when compiled in, probes the kernel by creating a minimal ruleset and fails with a different message ("Landlock not available") if the kernel lacks Landlock.

Source

Thrown at crates/zeroclaw-runtime/src/security/landlock.rs:321

    }
}

// Stub implementations for non-Linux or when feature is disabled
#[cfg(not(all(feature = "sandbox-landlock", target_os = "linux")))]
#[derive(Debug)]
pub struct LandlockSandbox;

#[cfg(not(all(feature = "sandbox-landlock", target_os = "linux")))]
impl LandlockSandbox {
    pub fn new() -> std::io::Result<Self> {
        Err(std::io::Error::new(
            std::io::ErrorKind::Unsupported,
            "Landlock is only supported on Linux with the sandbox-landlock feature",
        ))
    }

    pub fn with_workspace(_workspace_dir: Option<std::path::PathBuf>) -> std::io::Result<Self> {
        Err(std::io::Error::new(
            std::io::ErrorKind::Unsupported,
            "Landlock is only supported on Linux",
        ))
    }

    pub fn probe() -> std::io::Result<Self> {
        Err(std::io::Error::new(
            std::io::ErrorKind::Unsupported,
            "Landlock is only supported on Linux",
        ))
    }
}

#[cfg(not(all(feature = "sandbox-landlock", target_os = "linux")))]
impl Sandbox for LandlockSandbox {
    fn wrap_command(&self, _cmd: &mut std::process::Command) -> std::io::Result<()> {
        Err(std::io::Error::new(
            std::io::ErrorKind::Unsupported,

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Enable the feature in the dependency declaration so Linux builds compile the real implementation (see exampleFix)
  2. Switch the platform: Landlock cannot be used off Linux; select SeatbeltSandbox on macOS
  3. Treat ErrorKind::Unsupported as a signal to fall back to another sandbox backend rather than a fatal error
  4. Fix misleading operator messaging: this variant fires for feature-less Linux builds too, even though the text only mentions Linux

Example fix

# before (Cargo.toml)
[dependencies]
zeroclaw-runtime = { path = "../zeroclaw-runtime" } # default features: no sandbox-landlock

# after
[dependencies]
zeroclaw-runtime = { path = "../zeroclaw-runtime", features = ["sandbox-landlock"] } # Linux builds get the real LandlockSandbox
Defensive patterns

Strategy: validation

Validate before calling

if !cfg!(all(feature = "sandbox-landlock", target_os = "linux")) {
    // do not call LandlockSandbox::with_workspace(..); pick another backend
}

Type guard

fn is_unsupported(e: &std::io::Error) -> bool {
    e.kind() == std::io::ErrorKind::Unsupported
}

Try / catch

match LandlockSandbox::with_workspace(Some(ws)) {
    Ok(s) => s,
    Err(e) if e.kind() == std::io::ErrorKind::Unsupported => fallback_sandbox()?,
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling LandlockSandbox::with_workspace(Some(dir)) or with_workspace(None) from sandbox-factory or config-driven code on macOS/Windows, or on a Linux build without the sandbox-landlock feature enabled.

Common situations: Default-features builds of zeroclaw-runtime (sandbox-landlock omitted); cross-compilation targets; a config file that pins backend = "landlock" being shipped to non-Linux hosts; developer machines on macOS.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/b791880183a8e68e. Report an issue: GitHub.