fluent/fluentd · error · Fluent::ConfigError

empty value is specified in fields parameter

Error message

empty value is specified in fields parameter

What it means

The CSV formatter formats each record according to the fields array. During configure, empty-string entries are filtered out (fields.select{|f| !f.empty? }); if nothing remains the plugin raises ConfigError 'empty value is specified in fields parameter'. This fires both when fields is omitted entirely and when every entry is an empty string.

Source

Thrown at lib/fluent/plugin/formatter_csv.rb:58

      end

      def csv_thread_key
        csv_cacheable? ? "#{owner.plugin_id}_csv_formatter_#{@usage}_csv" : nil
      end

      def csv_for_thread
        if csv_cacheable?
          Thread.current[csv_thread_key] ||= CSV.new("".force_encoding(Encoding::ASCII_8BIT), **@generate_opts)
        else
          CSV.new("".force_encoding(Encoding::ASCII_8BIT), **@generate_opts)
        end
      end

      def configure(conf)
        super

        @fields = fields.select{|f| !f.empty? }
        raise ConfigError, "empty value is specified in fields parameter" if @fields.empty?

        if @fields.any? { |f| record_accessor_nested?(f) }
          @accessors = @fields.map { |f| record_accessor_create(f) }
          mformat = method(:format_with_nested_fields)
          singleton_class.module_eval do
            define_method(:format, mformat)
          end
        end

        @generate_opts = {col_sep: @delimiter, force_quotes: @force_quotes, headers: @fields,
                          row_sep: @add_newline ? :auto : "".force_encoding(Encoding::ASCII_8BIT)}
      end

      def format(tag, time, record)
        csv = csv_for_thread
        line = (csv << record).string.dup
        # Need manual cleanup because CSV writer doesn't provide such method.
        csv.rewind

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Set fields to the explicit column list, e.g. fields ["time","level","message"].
  2. If fields comes from a template/variable, assert it is non-empty before rendering the config.
  3. Validate with fluentd --dry-run to catch it at deploy time.

Example fix

# before
<match app.**>
  @type file
  <format>
    @type csv
  </format>
</match>
# after
<match app.**>
  @type file
  <format>
    @type csv
    fields ["time","level","message"]
  </format>
</match>
Defensive patterns

Strategy: validation

Validate before calling

# config lint: csv formatter must end up with at least one non-empty field
fields = conf_fields_for_csv_format.compact.map(&:strip).reject(&:empty?)
abort 'csv formatter: fields is empty' if fields.empty?
# authoritative: fluentd --dry-run -c /etc/fluent/fluent.conf

Try / catch

begin
  Fluent::Plugin.new_formatter('csv').configure(conf)
rescue Fluent::ConfigError => e
  abort "csv formatter config rejected: #{e.message}" # 'empty value is specified in fields parameter'
end

Prevention

When it happens

Trigger: A <format> @type csv block with no fields param, fields set to an empty string, or fields whose entries are all empty (e.g. stray commas produce empty entries but also at least one non-empty one, which would NOT raise).

Common situations: Enabling CSV output for out_file/file buffers without specifying columns; templated configs where the fields variable renders empty; commented-out fields lines.

Related errors


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