fluent/fluentd · error · Fluent::ConfigError

<system> is duplicated. <system> should be only one

Error message

<system> is duplicated. <system> should be only one

What it means

Fluent::ConfigError raised by SystemConfig.create (lib/fluent/system_config.rb:132) when the top-level configuration contains more than one <system> element. Fluentd requires exactly zero or one <system> block because it holds global process settings (workers, root_dir, log level) that cannot be merged.

Source

Thrown at lib/fluent/system_config.rb:132

    config_section :source_only_buffer, init: true, multi: false do
      config_param :flush_thread_count, :integer, default: 1
      config_param :overflow_action, :enum, list: [:throw_exception, :block, :drop_oldest_chunk], default: :drop_oldest_chunk
      config_param :path, :string, default: nil
      config_param :flush_interval, :time, default: nil
      config_param :chunk_limit_size, :size, default: nil
      config_param :total_limit_size, :size, default: nil
      config_param :compress, :enum, list: [:text, :gzip], default: nil
    end

    def force_stacktrace_level?
      @log.forced_stacktrace_level != :none
    end

    def self.create(conf, strict_config_value=false)
      systems = conf.elements(name: 'system')
      return SystemConfig.new if systems.empty?
      raise Fluent::ConfigError, "<system> is duplicated. <system> should be only one" if systems.size > 1

      SystemConfig.new(systems.first, strict_config_value)
    end

    def self.blank_system_config
      Fluent::Config::Element.new('<SYSTEM>', '', {}, [])
    end

    def self.overwrite_system_config(hash)
      older = defined?($_system_config) ? $_system_config : nil
      begin
        $_system_config = SystemConfig.new(Fluent::Config::Element.new('system', '', hash, []))
        yield
      ensure
        $_system_config = older
      end
    end

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Search the effective config for all <system> occurrences: grep -n '<system' fluent.conf and every included file (fluentd --dry-run -c fluent.conf also shows the merged config)
  2. Merge the settings from the duplicate blocks into a single <system> element
  3. If you use @include, ensure only one included file (or the main file) defines <system>, and keep the others free of it

Example fix

# before
<system>
  workers 4
</system>
<system>
  log_level info
</system>

# after
<system>
  workers 4
  log_level info
</system>
Defensive patterns

Strategy: validation

Validate before calling

require 'fluent/config'

conf = Fluent::Config.parse(File.read('fluent.conf'), 'fluent.conf', Dir.pwd, true)
systems = conf.elements(name: 'system')
raise 'multiple <system> blocks found' if systems.size > 1
# cheaper textual check across includes:
#   grep -c '<system>' fluent.conf included/*.conf  # each file: 0 or 1, total <= 1

Prevention

When it happens

Trigger: A fluent.conf containing two or more <system>...</system> elements — commonly the result of concatenating config snippets, using @include on files that each carry their own <system> block, or pasting a second block while editing.

Common situations: Composing a config from multiple @include'd fragments where each fragment was self-contained with its own <system>; upgrading tutorials that append a new <system> for log settings while the old one for workers remains; config-generator tools emitting a <system> block into both the main file and an included file.

Related errors


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