fluent/fluentd · error · Fluent::ConfigError

Missing <match> sections in <label #{@context}> section

Error message

Missing <match> sections in <label #{@context}> section

What it means

A <label NAME> section is an isolated routing namespace: events enter via <filter> chains and must exit through at least one <match> output owned by the label. Label#configure counts conf.elements('match') and raises this ConfigError when the label contains none (e.g. only filters, or is empty). Fluentd rejects the config at startup rather than silently dropping the label's events.

Source

Thrown at lib/fluent/label.rb:34

require 'fluent/agent'

module Fluent
  class Label < Agent
    def initialize(name, log:)
      super(log: log)

      @context = name
      @root_agent = nil
    end

    attr_accessor :root_agent

    def configure(conf)
      super

      if conf.elements('match').size == 0
        raise ConfigError, "Missing <match> sections in <label #{@context}> section"
      end
    end

    def emit_error_event(tag, time, record, e)
      @root_agent.emit_error_event(tag, time, record, e)
    end

    def handle_emits_error(tag, es, e)
      @root_agent.handle_emits_error(tag, es, e)
    end
  end
end

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Add a <match **> (or a narrower pattern) with an output plugin inside the label
  2. For @ERROR labels, terminate with a stdout/file/forward output so errors are visible
  3. Remove the label entirely if you no longer route events into it
  4. Verify label nesting: matches must be direct children of the <label>, not of a nested section

Example fix

# before
<label @ERROR>
  <filter **>
    @type record_transformer
    <record>
      hostname ${hostname}
    </record>
  </filter>
</label>

# after
<label @ERROR>
  <filter **>
    @type record_transformer
    <record>
      hostname ${hostname}
    </record>
  </filter>
  <match **>
    @type stdout
  </match>
</label>
Defensive patterns

Strategy: validation

Validate before calling

# Static config check before deploy
require 'fluent/config/parser'
conf = Fluent::Config.parse(path, 'fluent.conf', Dir.pwd, true)
conf.elements('label').each do |l|
  abort "label #{l.arg} has no <match>" if l.elements('match').empty?
end

Prevention

When it happens

Trigger: <label @ERROR> holding only a <filter> for error-event rewriting with no output; refactoring that moved the <match> out of a label; a label added as a placeholder without content.

Common situations: Building error-handling pipelines (@ERROR, @ROOT labels) and forgetting the terminal output; splitting large configs into snippets where the match lands in the wrong file; copy-paste of a filter-only label template.

Related errors


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