fluent/fluentd · error · Fluent::ConfigError
<buffer> section is configured, but plugin '#{self.class}' d
Error message
<buffer> section is configured, but plugin '#{self.class}' doesn't support buffering What it means
Fluent::Plugin::Output#configure raises this Fluent::ConfigError when the config contains a `<buffer>` section for an output plugin that implements neither `buffered` (a #write method) nor `delayed_commit` (#try_write) processing — only synchronous #process. Buffering capability is determined by which processing methods the plugin class defines, so a `<buffer>` block on a process-only plugin is meaningless and rejected at startup.
Source
Thrown at lib/fluent/plugin/output.rb:270
has_buffer_section = (conf.elements(name: 'buffer').size > 0)
has_flush_interval = conf.has_key?('flush_interval')
super
@num_errors_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "num_errors", help_text: "Number of count num errors")
@emit_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "emit_count", help_text: "Number of count emits")
@emit_records_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "emit_records", help_text: "Number of emit records")
@emit_size_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "emit_size", help_text: "Total size of emit events")
@write_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "write_count", help_text: "Number of writing events")
@write_secondary_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "write_secondary_count", help_text: "Number of writing events in secondary")
@rollback_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "rollback_count", help_text: "Number of rollbacking operations")
@flush_time_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "flush_time_count", help_text: "Count of flush time")
@slow_flush_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "slow_flush_count", help_text: "Count of slow flush occurred time(s)")
@drop_oldest_chunk_count_metrics = metrics_create(namespace: "fluentd", subsystem: "output", name: "drop_oldest_chunk_count", help_text: "Number of count that old chunk were discarded with drop_oldest_chunk")
if has_buffer_section
unless implement?(:buffered) || implement?(:delayed_commit)
raise Fluent::ConfigError, "<buffer> section is configured, but plugin '#{self.class}' doesn't support buffering"
end
@buffering = true
else # no buffer sections
if implement?(:synchronous)
if !implement?(:buffered) && !implement?(:delayed_commit)
if @as_secondary
raise Fluent::ConfigError, "secondary plugin '#{self.class}' must support buffering, but doesn't."
end
@buffering = false
else
if @as_secondary
# secondary plugin always works as buffered plugin without buffer instance
@buffering = true
else
# @buffering.nil? shows that enabling buffering or not will be decided in lazy way in #start
@buffering = nil
end
endView on GitHub (pinned to dd45c6e18d)
Solutions
- Remove the <buffer> section — the plugin (e.g. out_copy) forwards events synchronously by design
- If you need buffering, wrap the target in a buffering-capable output (e.g. route to @type forward/file/http which implement #write) and put the sync plugin behind it
- Plugin authors: define #write(chunk) (buffered) or #try_write(chunk) + #commit_write (delayed commit) to accept <buffer>
Example fix
# before
<match **>
@type copy
<store> @type stdout </store>
<buffer> # out_copy supports only synchronous processing
flush_interval 1s
</buffer>
</match>
# after
<match **>
@type copy
<store> @type stdout </store>
</match>
# (buffer the buffered-capable stores individually if needed) Defensive patterns
Strategy: type-guard
Validate before calling
# For plugin authors / test rigs: probe capabilities before accepting a <buffer> section
plugin = Fluent::Plugin.new_output('copy')
supports_buffering = plugin.implement?(:buffered) || plugin.implement?(:delayed_commit)
raise '<buffer> not supported by this plugin' if has_buffer_section && !supports_buffering Type guard
# Type guard over plugin capabilities (Ruby)
def bufferable_output?(plugin_instance)
plugin_instance.implement?(:buffered) || plugin_instance.implement?(:delayed_commit)
end
bufferable_output?(Fluent::Plugin.new_output('http')) # => true (defines #write)
bufferable_output?(Fluent::Plugin.new_output('copy')) # => false (defines only #process) Try / catch
# In config tooling:
begin
Fluent::Test::Driver::Output.new(plugin).configure(conf_str)
rescue Fluent::ConfigError => e
fail "buffer section rejected: #{e.message}"
end Prevention
- Check a plugin's processing contract before adding <buffer>: #write (buffered) or #try_write (delayed) — #process-only plugins reject it
- Don't put <buffer> on out_copy/out_relabel-style routers; buffer the fan-out targets instead
- Plugin authors: write a configure test with a <buffer> section so capability regressions fail in CI
When it happens
Trigger: Adding `<buffer> ... </buffer>` to a synchronous-only output — stock examples: out_copy, out_relabel-style routers, most custom plugins that define only `process`. Configure fails before any data is processed.
Common situations: Users adding buffer/flush tuning to `<match> @type copy` hoping to smooth bursts; plugin authors forgetting to define #write; configs migrated from v0.12 buffered_* compat plugins.
Related errors
- secondary plugin '#{self.class}' must support buffering, but
- buffer path is not configured. specify 'path' in <buffer>
- This plugin can only be used in the <secondary> section
- out_secondary_file: basename or directory has an incompatibl
- out_secondary_file: basename or directory has an incompatibl
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/ce5fef8af2bacb95.
Report an issue: GitHub.