shadowsocks/shadowsocks-rust · error

Failed to create file writer for logging

Error message

Failed to create file writer for logging

What it means

Panic when the tracing-based logging subsystem cannot create the file writer for a file-logging layer in make_layer: make_file_writer(bin_name, self) returned Err (unwritable/missing directory, permission denied, disk error) and expect('Failed to create file writer for logging') panics, as noted by the inline comment about the lack of graceful handling.

Source

Thrown at src/logging/tracing.rs:66

}

impl MakeLayer for LogConsoleWriterConfig {
    fn make_layer(&self, bin_name: &str, global: &LogConfig) -> BoxedLayer {
        let level = self.level.unwrap_or(global.level);
        let format = apply_override(&global.format, &self.format);
        let ansi = io::stdout().is_terminal();
        make_fmt_layer(bin_name, level, &format, ansi, io::stdout)
    }
}

impl MakeLayer for LogFileWriterConfig {
    fn make_layer(&self, bin_name: &str, global: &LogConfig) -> BoxedLayer {
        let level = self.level.unwrap_or(global.level);
        let format = apply_override(&global.format, &self.format);

        let file_writer = make_file_writer(bin_name, self)
            // don't have the room for a more graceful error handling here
            .expect("Failed to create file writer for logging");
        make_fmt_layer(bin_name, level, &format, false, file_writer)
    }
}

#[cfg(unix)]
impl MakeLayer for LogSyslogWriterConfig {
    fn make_layer(&self, bin_name: &str, global: &LogConfig) -> BoxedLayer {
        let level = self.level.unwrap_or(global.level);
        let format = apply_override(&global.format, &self.format);

        let syslog_writer = make_syslog_writer(bin_name, self);
        make_fmt_layer(bin_name, level, &format, false, syslog_writer)
    }
}

/// Boilerplate for configuring a `fmt::Layer` with `level` and `format` for different writers.
fn make_fmt_layer<W>(bin_name: &str, level: u32, format: &LogFormatConfig, ansi: bool, writer: W) -> BoxedLayer
where

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. Verify the log directory exists and is writable by the process user before startup
  2. Use an absolute log file path in the config and create the directory in your launch script
  3. Fall back to console logging if the file writer fails (patch or wrap make_layer)
  4. Run as a user with correct permissions or adjust log-dir ownership

Example fix

// before
let file_writer = make_file_writer(bin_name, self)
    .expect("Failed to create file writer for logging");
// after
std::fs::create_dir_all(&log_dir)?;
let file_writer = make_file_writer(bin_name, self)
    .unwrap_or_else(|e| {
        eprintln!("file logging disabled: {}", e);
        make_console_writer()
    });
Defensive patterns

Strategy: fallback

Validate before calling

fn ensure_log_dir_writable(dir: &Path) -> Result<(), String> {
    std::fs::create_dir_all(dir).map_err(|e| format!("cannot create log dir {:?}: {}", dir, e))?;
    let probe = dir.join(".write_probe");
    std::fs::write(&probe, b"").map_err(|e| format!("log dir {:?} not writable: {}", dir, e))?;
    let _ = std::fs::remove_file(&probe);
    Ok(())
}

Try / catch

// expect() panics; pre-flight the directory and fall back to console logging on failure
let file_writer = match make_file_writer(bin_name, self) {
    Ok(w) => w,
    Err(e) => { eprintln!("file logging unavailable: {}", e); return make_console_layer(); }
};

Prevention

When it happens

Trigger: Configuring a file logger (LogConfig with file output / LogTracingFileConfig) where the log directory doesn't exist, is not writable, or a rotation path is invalid; make_layer then panics while assembling the layer stack.

Common situations: Daemon running as an unprivileged user with a log dir owned by root; misconfigured log-file path (relative path resolving under a read-only cwd); disk-full or deleted log directory at startup.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09). Data as JSON: /api/errors/0d2e33b80b85caf2. Report an issue: GitHub.