Skip to content

Log file permissions not preserved after rotation (umask applied instead of configured mode) #7613

@jules-w2

Description

@jules-w2

Summary

When a log file is rotated, the newly created file loses the permissions set via the mode parameter in the Caddyfile. The configured mode is only reliably applied at initial file creation, not after rotation.

Environment

  • Caddy v2 (latest, custom build with plugins)
  • Linux (Debian/Ubuntu)
  • systemd service with default umask (0022)

Configuration

log {
    output file /var/log/caddy/app.log {
        mode 0660
    }
}

Expected behavior

After log rotation, the new app.log file should have mode 0660, matching the configured mode.

Actual behavior

After rotation, the new file is created with mode 0640 (the configured 0660 masked by the process umask 0022).

Root cause

There is an inconsistency between initial file creation and post-rotation file creation:

Initial creation (FileWriter.OpenWriter() in filewriter.go):

f, err := os.OpenFile(fw.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, modeIfCreating)
// ...
if existingInfo.Mode() != os.FileMode(fw.Mode) {
    os.Chmod(fw.Filename, os.FileMode(fw.Mode))  // ← explicit chmod, bypasses umask ✓
}

Post-rotation (openNew() in timberjack):

f, err := os.OpenFile(name, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, finalMode)
// no os.Chmod → umask wins ✗

Since os.OpenFile applies the process umask, the resulting permissions are 0660 & ~0022 = 0640. The explicit os.Chmod that Caddy does at initial creation is missing from timberjack's rotation path.

Impact

This breaks any setup where a non-root user in the caddy group needs to access log files (e.g. running caddy validate as a deploy user). It works initially, then silently breaks after the first rotation — making it hard to diagnose.

Workaround

Setting UMask=0007 in the systemd unit prevents the umask from stripping the group-write bit. But the underlying issue remains: the configured mode should be respected regardless of the process umask, as it is during initial creation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions