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
- Add a <match **> (or a narrower pattern) with an output plugin inside the label
- For @ERROR labels, terminate with a stdout/file/forward output so errors are visible
- Remove the label entirely if you no longer route events into it
- 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
- End every <label> with a catch-all <match **> output
- Lint label sections in CI with a config dry-run (fluentd --dry-run -c)
- Keep each label's filters and its terminal match in the same config snippet
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
- invalid match - regex
- Unknown #{@kind} plugin '#{type}'. Run 'gem search -rd fluen
- Missing '@type' parameter on <#{e.name}> directive
- 'format' parameter is required
- both of utc and localtime are specified, use only one of the
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/439861a0746c16bd.
Report an issue: GitHub.