fluent/fluentd · error · Fluent::ConfigError

out_secondary_file: basename or directory has an incompatibl

Error message

out_secondary_file: basename or directory has an incompatible placeholder, remove time formats, like `%Y%m%d`, from basename or directory

What it means

SecondaryFileOutput#configure validates its output path against the PRIMARY buffer's chunk keys. If the primary <buffer> has no `time` chunk key (@chunk_key_time false) but the directory/basename string contains strftime directives (detected by has_time_format?: the string changes when run through Time.now.strftime), this Fluent::ConfigError fires. The secondary writes chunks the primary already queued, and without a time chunk key there is no time value to expand %Y%m%d-style placeholders with.

Source

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

          }
        when :gzip
          File.open(path, "ab", @file_perm) {|f|
            f.flock(File::LOCK_EX)
            gz = Zlib::GzipWriter.new(f)
            chunk.write_to(gz)
            gz.close
          }
        end
      end
    end

    private

    def validate_compatible_with_primary_buffer!(path_without_suffix)
      placeholders = path_without_suffix.scan(PLACEHOLDER_REGEX).flat_map(&:first) # to trim suffix [\d+]

      if !@chunk_key_time && has_time_format?(path_without_suffix)
        raise Fluent::ConfigError, "out_secondary_file: basename or directory has an incompatible placeholder, remove time formats, like `%Y%m%d`, from basename or directory"
      end

      if !@chunk_key_tag && (ph = placeholders.find { |placeholder| placeholder.match?(/tag(\[\d+\])?/) })
        raise Fluent::ConfigError, "out_secondary_file: basename or directory has an incompatible placeholder #{ph}, remove tag placeholder, like `${tag}`, from basename or directory"
      end

      vars = placeholders.reject { |placeholder| placeholder.match?(/tag(\[\d+\])?/) || (placeholder == 'chunk_id') }

      if ph = vars.find { |v| !@chunk_keys.include?(v) }
        raise Fluent::ConfigError, "out_secondary_file: basename or directory has an incompatible placeholder #{ph}, remove variable placeholder, like `${varname}`, from basename or directory"
      end
    end

    def has_time_format?(str)
      str != Time.now.strftime(str)
    end

    def generate_path(path_without_suffix)

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Add the time key to the primary buffer: `<buffer time>` (usually `<buffer time, tag>`) with an appropriate `timekey`, so chunks carry the time needed to expand the format
  2. Or remove the time formats from directory/basename and use a flat path
  3. Confirm with `fluentd --dry-run` — this is caught at configure time

Example fix

# before
<match **>
  @type forward
  <buffer tag>          # no time chunk key
    ... 
  </buffer>
  <secondary>
    @type secondary_file
    directory /var/log/dump/%Y%m%d
  </secondary>
</match>

# after
<match **>
  @type forward
  <buffer time, tag>
    timekey 1d
  </buffer>
  <secondary>
    @type secondary_file
    directory /var/log/dump/%Y%m%d
  </secondary>
</match>
Defensive patterns

Strategy: validation

Validate before calling

# Check: time formats in the secondary path require a time chunk key in the primary buffer
buffer = match_element.elements.find { |e| e.name == 'buffer' }
keys = buffer && buffer.arg.to_s.split(',').map(&:strip)
has_time_key = keys && keys.include?('time')
path = File.join(directory, basename || 'dump.bin')
raise 'time format in path but primary buffer has no time key' if !has_time_key && path != Time.now.strftime(path)

Prevention

When it happens

Trigger: `<buffer>` or `<buffer tag>` (no `time` key) combined with a secondary_file path containing time formats, e.g. `directory /var/log/dump/%Y%m%d` or `basename dump.%Y%m%d.bin`. Any literal %Y/%m/%d/%H anywhere in the path triggers it, not just ${time} placeholders.

Common situations: Copying date-partitioned paths from out_file configs; adding time-based directory layout to the secondary without switching the primary to `<buffer time>`; a basename that happens to contain a %-escape from a templating system.

Related errors


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