fluent/fluentd · critical · Fluent::ConfigError

Missing '@type' parameter on <#{e.name}> directive

Error message

Missing '@type' parameter on <#{e.name}> directive

What it means

Raised as Fluent::ConfigError by Fluent::Agent#configure while walking every <filter> and <match> element: it reads only e['@type'], and a nil value aborts configuration with 'Missing @type parameter on <match>/<filter> directive'. Elements marked for another worker (multi-worker setups) are skipped, but everything else must name an output or filter plugin.

Source

Thrown at lib/fluent/agent.rb:70

    attr_reader :log
    attr_reader :outputs
    attr_reader :filters
    attr_reader :context
    attr_reader :event_router
    attr_reader :error_collector

    def configure(conf)
      super

      # initialize <match> and <filter> elements
      conf.elements('filter', 'match').each { |e|
        if !Fluent::Engine.supervisor_mode && e.for_another_worker?
          next
        end
        pattern = e.arg.empty? ? '**' : e.arg
        type = e['@type']
        raise ConfigError, "Missing '@type' parameter on <#{e.name}> directive" unless type
        if e.name == 'filter'
          add_filter(type, pattern, e)
        else
          add_match(type, pattern, e)
        end
      }
    end

    def lifecycle_control_list
      return @lifecycle_control_list if @lifecycle_control_list

      lifecycle_control_list = {
        input: [],
        output_with_router: [],
        filter: [],
        output: [],
      }
      if self.respond_to?(:inputs)

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Add @type <plugin_name> as the first parameter of every <match> and <filter> block (e.g. @type stdout, @type record_transformer)
  2. Replace legacy 'type' keys with '@type' - the v1 agent only reads '@type'
  3. Validate before deploy with fluentd --dry-run -c /etc/fluent/fluent.conf so startup never hits it in production

Example fix

# before
<match myapp.**>
</match>

# after
<match myapp.**>
  @type stdout
</match>
Defensive patterns

Strategy: validation

Validate before calling

require 'fluent/config'
conf = Fluent::Config.parse(File.read('/etc/fluent/fluent.conf'), 'fluent.conf', Dir.pwd, true)
conf.elements('filter', 'match').each do |e|
  abort "missing @type in <#{e.name}>" unless e['@type']
end

Prevention

When it happens

Trigger: A <match pattern> or <filter pattern> block with no @type line at all; using the v0.12-era 'type file' spelling, which this v1 code path never reads; an empty placeholder match block left in the config.

Common situations: Hand-edited configs after copying a template; migrating v0.12 configs where 'type' was renamed to '@type'; commented-out @type lines accidentally left commented.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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