fluent/fluentd · error · Fluent::ConfigError

out_secondary_file: `#{@directory}` should be writable

Error message

out_secondary_file: `#{@directory}` should be writable

What it means

SecondaryFileOutput#configure probes writability via Fluent::FileUtil.writable_p?(directory/basename): it walks up to the nearest existing ancestor directory of the target path and checks `File.writable?` under the Fluentd process user; if that ancestor exists but is not writable (or the target itself exists and is unwritable), this Fluent::ConfigError is raised. Note missing intermediate directories are fine as long as some ancestor (e.g. /var/log) is writable — they are mkdir_p'ed later at write time.

Source

Thrown at lib/fluent/plugin/out_secondary_file.rb:59

      end

      if @basename.include?("/")
        raise Fluent::ConfigError, "basename should not include `/`"
      end

      @path_without_suffix = File.join(@directory, @basename)
      validate_compatible_with_primary_buffer!(@path_without_suffix)

      @suffix = case @compress
                when :text
                  ""
                when :gzip
                  ".gz"
                end

      test_path = @path_without_suffix
      unless Fluent::FileUtil.writable_p?(test_path)
        raise Fluent::ConfigError, "out_secondary_file: `#{@directory}` should be writable"
      end

      @dir_perm = system_config.dir_permission || Fluent::DEFAULT_DIR_PERMISSION
      @file_perm = system_config.file_permission || Fluent::DEFAULT_FILE_PERMISSION
    end

    def multi_workers_ready?
      true
    end

    def write(chunk)
      path_without_suffix = extract_placeholders(@path_without_suffix, chunk)
      generate_path(path_without_suffix) do |path|
        FileUtils.mkdir_p File.dirname(path), mode: @dir_perm

        case @compress
        when :text
          File.open(path, "ab", @file_perm) {|f|

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Create/own the directory for the fluentd user: `install -d -o fluent -g fluent /var/log/fluent/dump`
  2. If the file already exists, fix its owner/permissions too (`chown fluent:fluent <file>`)
  3. On containers, mount a writable volume at the directory (emptyDir, PVC) instead of writing into the image

Example fix

# before
# /var/log/fluent owned by root, fluentd runs as 'fluent'
sudo mkdir -p /var/log/fluent/failed

# after
sudo mkdir -p /var/log/fluent/failed
sudo chown -R fluent:fluent /var/log/fluent
Defensive patterns

Strategy: validation

Validate before calling

# Mirror writable_p?'s logic as a pre-start check (runs as the fluentd user):
require 'fileutils'
path = File.join(directory, basename || 'dump.bin')
dir = File.dirname(path)
dir = File.dirname(dir) until File.exist?(dir)
unless File.directory?(dir) && File.writable?(dir)
  abort "#{dir} not writable by #{Etc.getlogin rescue Process.uid}"
end

Prevention

When it happens

Trigger: Running fluentd under the `fluent` user while the nearest existing directory (often /var/log/fluent or the configured directory) is owned by root or lacks write permission; read-only mounts (immutable containers, ro volumes); the target file already exists but is owned by another user.

Common situations: systemd units dropping from root to User=fluent without chowning log dirs; Docker/Kubernetes readOnlyRootFilesystem without an emptyDir mount at the directory; SELinux denials on top of DAC permissions.

Related errors


AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21). Data as JSON: /api/errors/51728555cca64826. Report an issue: GitHub.