slimtoolkit/slim · error
failed to set log output destination to %q: %w
Error message
failed to set log output destination to %q: %w
What it means
After the touch succeeds, configureLogger opens the log file with os.OpenFile(O_WRONLY|O_CREATE|O_APPEND, 0644) to attach it as logrus output. If the OS refuses to open the file for writing, this wrapped error is returned and the sensor fails to start.
Source
Thrown at pkg/app/sensor/logger.go:36
logFile string,
) error {
if err := setLogLevel(enableDebug, levelName); err != nil {
return fmt.Errorf("failed to set log-level: %v", err)
}
if err := setLogFormat(format); err != nil {
return fmt.Errorf("failed to set log format: %v", err)
}
if len(logFile) > 0 {
// This touch is not ideal - need to understand how to merge this logic with artifacts.PrepareEnv().
if err := fsutil.Touch(logFile); err != nil {
return fmt.Errorf("failed to set log output destination to %q, touch failed with: %v", logFile, err)
}
f, err := os.OpenFile(logFile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
return fmt.Errorf("failed to set log output destination to %q: %w", logFile, err)
}
log.SetOutput(f)
}
return nil
}
func setLogFormat(format string) error {
switch format {
case "text":
log.SetFormatter(&log.TextFormatter{DisableColors: true})
case "json":
log.SetFormatter(&log.JSONFormatter{})
default:
return fmt.Errorf("unknown log-format %q", format)
}
View on GitHub (pinned to 81940d17fa)
Solutions
- Fix ownership/mode of the log file (chmod 0644 or chown to the sensor's uid).
- Ensure the logFile path is a regular writable file, not a directory or broken symlink.
- Check 'too many open files' limits if the wrapped error is EMFILE and raise ulimit -n.
Example fix
// before -rw------- root root /var/log/sensor/sensor.log // after chmod 0644 /var/log/sensor/sensor.log && chown sensor:sensor /var/log/sensor/sensor.log
Defensive patterns
Strategy: validation
Validate before calling
func canAppend(path string) error {
fi, err := os.Stat(path)
if err != nil { return err }
if fi.IsDir() { return fmt.Errorf("%s is a directory", path) }
f, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND, 0644)
if err != nil { return err }
return f.Close()
} Type guard
func isOpenDenied(err error) bool {
var pe *fs.PathError
return errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission)
} Try / catch
if err := Run(ctx); err != nil && strings.Contains(err.Error(), "failed to set log output destination") {
fmt.Fprintf(os.Stderr, "cannot open log file for append: %v\n", err)
os.Exit(1)
} Prevention
- Set the log file mode/owner so the sensor uid can write (0644 + correct owner).
- Avoid log rotation tooling that replaces the file with a directory or read-only link.
- Raise the process fd limit if running with many open files.
- Fall back to stdout logging if the file cannot be opened, rather than aborting.
When it happens
Trigger: The log file exists but is not writable by the sensor process (wrong owner/mode), the path is a directory, a symlink loop exists, or the fd limit (EMFILE) is reached.
Common situations: Log file pre-created by an init step with restrictive 0600 root ownership; SELinux/AppArmor denying write; log rotation tooling replaced the file with a directory or a read-only link.
Related errors
- cannot create execution - open event file %q failed: %w
- failed to set log output destination to %q, touch failed wit
- cannot open file %q to duplicate app's %s stream: %w
- cannot create execution - touch event file %q failed: %w
- invalid context directory
AI-assisted analysis of slimtoolkit/slim@81940d17fa (2026-08-31).
Data as JSON: /api/errors/cfd9a91c24d8e61c.
Report an issue: GitHub.