fluent/fluentd · error · Fluent::ConfigError

Parameter '#{name}: #{string}' doesn't have enough placehold

Error message

Parameter '#{name}: #{string}' doesn't have enough placeholders for keys #{not_specified.join(',')}

What it means

Some buffer chunk keys have no corresponding `${key}` placeholder in the parameter (`(chunk_keys - keys).size > 0` in `validate_keys!`). Records with different values for the missing key would land in distinct chunks that render the identical path/value, silently merging data you asked to separate — so configure fails, listing the keys without placeholders.

Source

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

        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
            not_specified = (chunk_keys - keys).sort
            raise Fluent::ConfigError, "Parameter '#{name}: #{string}' doesn't have enough placeholders for keys #{not_specified.join(',')}"
          end
          if (keys - chunk_keys).size > 0
            not_satisfied = (keys - chunk_keys).sort
            raise Fluent::ConfigError, "Parameter '#{name}: #{string}' has placeholders, but chunk keys doesn't have keys #{not_satisfied.join(',')}"
          end
        end
      end

      TIME_KEY_PLACEHOLDER_THRESHOLDS = [
        [1, :second, '%S'],
        [60, :minute, '%M'],
        [3600, :hour, '%H'],
        [86400, :day, '%d'],
      ]
      TIMESTAMP_CHECK_BASE_TIME = Time.parse("2016-01-01 00:00:00 UTC")
      # it's not validated to use timekey larger than 1 day
      def get_placeholders_time(str)
        base_str = TIMESTAMP_CHECK_BASE_TIME.strftime(str)

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Add the missing placeholder(s): `path /logs/${tenant}/${env}.log`
  2. Or remove the unneeded key from the `<buffer ...>` chunk key list
  3. Keep the two lists in sync in code review — the error names exactly which keys are missing

Example fix

# before
<buffer tenant,env>
  @type file
</buffer>
path /logs/${tenant}.log

# after
<buffer tenant,env>
  @type file
</buffer>
path /logs/${tenant}/${env}.log
Defensive patterns

Strategy: validation

Validate before calling

# keep chunk keys and path placeholders in sync
chunk_keys = %w[tenant env]
path = '/logs/${tenant}.log'
used = path.scan(/\$\{([^}]+)\}/).flatten - %w[tag chunk_id]
missing = chunk_keys - used
abort \"chunk keys without placeholders: #{missing.join(', ')}\" unless missing.empty?
fluentd --dry-run -c /etc/fluent/fluent.conf

Type guard

def placeholders_cover_chunk_keys?(chunk_keys, template)
  used = template.scan(/\$\{([^}]+)\}/).flatten - %w[tag chunk_id]
  (chunk_keys - used).empty?
end

Prevention

When it happens

Trigger: `<buffer tenant,env>` with `path /logs/${tenant}.log` — `env` has no `${env}` in the path; the error lists `env` via `not_specified.join(',')`. Applies to any placeholder-validated parameter missing placeholders for configured chunk keys.

Common situations: Adding a chunk key for cardinality control while the path template lags behind; deleting a `${key}` from the path during a refactor but leaving the key in the buffer line.

Related errors


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