fluent/fluentd · error · Fluent::ConfigError

Parameter '#{name}: #{string}' doesn't have timestamp placeh

Error message

Parameter '#{name}: #{string}' doesn't have timestamp placeholder for #{title}('#{example}') for timekey #{timekey.to_i}

What it means

The time directives present in the parameter are coarser than the timekey: `get_placeholders_time` computes the granularity (`sec`) of the finest directive in the string (e.g. only `%d` → 86400s), and `timekey < sec` means several distinct chunks would render the same path value. The error names the coarsest offender via `title`/`example` (e.g. day('%d')) and the configured timekey.

Source

Thrown at lib/fluent/plugin/output.rb:739

          when :time then validate_time!
          when :tag  then validate_tag!
          when :keys then validate_keys!
          end
        end

        def validate_time!
          sec = @argument[:sec]
          title = @argument[:title]
          example = @argument[:example]
          timekey = @argument[:timekey]
          if !sec && timekey
            raise Fluent::ConfigError, "Parameter '#{name}: #{string}' doesn't have timestamp placeholders for timekey #{timekey.to_i}"
          end
          if sec && !timekey
            raise Fluent::ConfigError, "Parameter '#{name}: #{string}' has timestamp placeholders, but chunk key 'time' is not configured"
          end
          if sec && timekey && timekey < sec
            raise Fluent::ConfigError, "Parameter '#{name}: #{string}' doesn't have timestamp placeholder for #{title}('#{example}') for timekey #{timekey.to_i}"
          end
        end

        def validate_tag!
          parts = @argument[:parts]
          tagkey = @argument[:tagkey]
          if tagkey && parts.empty?
            raise Fluent::ConfigError, "Parameter '#{name}: #{string}' doesn't have tag placeholder"
          end
          if !tagkey && !parts.empty?
            raise Fluent::ConfigError, "Parameter '#{name}: #{string}' has tag placeholders, but chunk key 'tag' is not configured"
          end
        end

        def validate_keys!
          keys = @argument[:keys]
          chunk_keys = @argument[:chunkkeys]
          if (chunk_keys - keys).size > 0

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Add a directive matching the timekey granularity: for 1h add `%H`, for 1m add `%M`, for 1s add `%S`
  2. Or relax the timekey to match the path granularity (e.g. timekey 1d with a %Y%m%d path)
  3. Double-check the mapping: %S=1s, %M=60s, %H=3600s, %d=86400s vs your timekey seconds

Example fix

# before
timekey 1h
path /logs/app.%Y%m%d.log

# after
timekey 1h
path /logs/app.%Y%m%d%H.log
Defensive patterns

Strategy: validation

Validate before calling

# Ruby pre-check: finest directive granularity must be <= timekey
GRAN = { '%S' => 1, '%M' => 60, '%H' => 3600, '%d' => 86400 }
path = '/logs/app.%Y%m%d.log'; timekey = 3600
finest = GRAN.values.select { |s| GRAN.any? { |d, v| v == s && path.include?(d) } }.min || 0
abort 'path too coarse for timekey' if timekey < finest
fluentd --dry-run -c /etc/fluent/fluent.conf

Type guard

def timekey_covers_path?(timekey, path)
  gran = { '%S' => 1, '%M' => 60, '%H' => 3600, '%d' => 86400 }
  finest = gran.select { |d, _| path.include?(d) }.values.min
  finest.nil? || timekey >= finest
end

Prevention

When it happens

Trigger: `timekey 1h` with `path /logs/app.%Y%m%d.log` (finest directive is %d = 86400s > 3600s); `timekey 30s` with only `%Y%m%d%H`; any combination where the path varies slower than the chunk window.

Common situations: Tightening `timekey` for smaller files (1d → 1h) without adding `%H` to the path; using a date-only filename inherited from an example with a per-hour timekey.

Related errors


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