fluent/fluentd · critical · Fluent::ConfigError

this plugin '#{self.class}' allows <buffer tag> only

Error message

this plugin '#{self.class}' allows <buffer tag> only

What it means

Raised as Fluent::ConfigError in Fluent::Compat::ObjectBufferedOutput#configure, the shim for v0.12 ObjectBufferedOutput plugins (plugins implementing write_objects(tag, chunk)). config_style is :v1 when an explicit <buffer> section is present; when the chunk keys parsed from it are exactly ['tag'] the shim raises. Despite the message text ('allows <buffer tag> only'), what is rejected is precisely an explicitly written <buffer tag> section: tag-flushed buffering is wired internally by the shim (it appends its own <buffer tag> when translating v0-style config), not through v1 buffer syntax.

Source

Thrown at lib/fluent/compat/output.rb:501

              if older == 'buffer_queue_full_action' && conf[older] == 'exception'
                buf_params[newer] = 'throw_exception'
              else
                buf_params[newer] = conf[older]
              end
            end
          end

          conf.elements << Fluent::Config::Element.new('buffer', 'tag', buf_params, [])
        end

        ParserUtils.convert_parser_conf(conf)
        FormatterUtils.convert_formatter_conf(conf)

        super

        if config_style == :v1
          if @buffer_config.chunk_keys == ['tag']
            raise Fluent::ConfigError, "this plugin '#{self.class}' allows <buffer tag> only"
          end
        end

        self.extend BufferedChunkMixin
      end

      def format_stream(tag, es) # for BufferedOutputTestDriver
        if @compress == :gzip
          es.to_compressed_msgpack_stream(time_int: @time_as_integer)
        else
          es.to_msgpack_stream(time_int: @time_as_integer)
        end
      end

      def write(chunk)
        write_objects(chunk.metadata.tag, chunk)
      end

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Remove the explicit <buffer tag> section and configure buffering with the plugin's v0.12 parameters (buffer_type, flush_interval, retry_limit)
  2. Upgrade the plugin to a v1-API version that supports <buffer ...> sections natively
  3. Check compatibility with fluentd --dry-run -c <config> before restart

Example fix

# before (v0.12 ObjectBufferedOutput plugin, v1-style config)
<match app.**>
  @type legacy_object_output
  <buffer tag>
    @type memory
  </buffer>
</match>

# after
<match app.**>
  @type legacy_object_output
  buffer_type memory
  flush_interval 5s
</match>
Defensive patterns

Strategy: validation

Validate before calling

# catch it before deploy:
#   fluentd --dry-run -c /etc/fluent/fluent.conf
# in code, detect the incompatible combination:
legacy = plugin.class.ancestors.any? { |a| a.name == 'Fluent::Compat::ObjectBufferedOutput' }
buffer_arg = conf.elements.find { |e| e.name == 'buffer' }&.arg.to_s.strip
abort 'v0.12 ObjectBufferedOutput plugin rejects an explicit <buffer tag> section' if legacy && buffer_arg == 'tag'

Prevention

When it happens

Trigger: A v1-style config with an explicit <buffer tag> section on a v0.12 ObjectBufferedOutput plugin; reusing a config written for a v1 plugin on an unmigrated legacy plugin.

Common situations: Copying modern config examples onto old plugin versions; config-management templates shared across plugins of mixed API generations.

Related errors


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