fluent/fluentd · error · ArgumentError
Unknown feature for parser plugin: #{feature}
Error message
Unknown feature for parser plugin: #{feature} What it means
Parser#implement?(feature) (lib/fluent/plugin/parser.rb:169) is the feature-detection API for optional parser capabilities. It only knows exactly two symbols — :parse_io and :parse_partial_data — and raises ArgumentError for anything else. Inputs like in_exec and out_exec_filter branch on these flags, so passing an unrecognized symbol is a programming error (often a typo or a feature name from a different fluentd version).
Source
Thrown at lib/fluent/plugin/parser.rb:169
rescue UncatchableError
log.warn "parsing timed out with #{self.class}: text = #{text}"
# Return nil instead of raising error. in_tail or other plugin can emit broken line.
yield nil, nil
end
def call(*a, &b)
# Keep backward compatibility for existing plugins
# TODO: warn when deprecated
parse(*a, &b)
end
def implement?(feature)
methods_of_plugin = self.class.instance_methods(false)
case feature
when :parse_io then methods_of_plugin.include?(:parse_io)
when :parse_partial_data then methods_of_plugin.include?(:parse_partial_data)
else
raise ArgumentError, "Unknown feature for parser plugin: #{feature}"
end
end
def parse_io(io, &block)
raise NotImplementedError, "Optional API #parse_io is not implemented"
end
def parse_partial_data(data, &block)
raise NotImplementedError, "Optional API #parse_partial_data is not implemented"
end
def parse_time(record)
if @time_key && record.respond_to?(:has_key?) && record.has_key?(@time_key)
src = if @keep_time_key
record[@time_key]
else
record.delete(@time_key)
endView on GitHub (pinned to dd45c6e18d)
Solutions
- Use only :parse_io or :parse_partial_data with parser plugins.
- For output plugins' capabilities, call implement? on the output instance with :synchronous/:buffered/:delayed_commit/:custom_format instead.
- If you must probe arbitrary features defensively, rescue ArgumentError and treat it as false.
- Upgrade fluentd to the version the plugin was written for when the feature name genuinely should exist.
Example fix
# before if parser.implement?(:parse_stream) # ArgumentError: unknown feature # after if parser.implement?(:parse_io) parser.parse_io(io, &callback) elsif parser.implement?(:parse_partial_data) parser.parse_partial_data(io.readpartial(4096), &callback) end
Defensive patterns
Strategy: validation
Validate before calling
PARSER_FEATURES = %i[parse_io parse_partial_data].freeze
unless PARSER_FEATURES.include?(feature)
log.warn "unknown parser feature #{feature}; skipping"
return false
end
parser.implement?(feature) Type guard
def known_parser_feature?(f) %i[parse_io parse_partial_data].include?(f) end
Try / catch
rescue ArgumentError false # unknown feature on this fluentd version; treat as unsupported
Prevention
- Only probe :parse_io / :parse_partial_data on parsers.
- Freeze a feature whitelist constant in your plugin and check against it.
- Pin the fluentd version your plugin targets so feature vocabularies match.
When it happens
Trigger: Calling parser.implement?(:parseIO), :partial_data, :parse_stream, or any string instead of a symbol; a plugin written against a newer fluentd probing a feature name this version does not define; using the Output plugin's implement? vocabulary (:synchronous, :buffered, :delayed_commit, :custom_format) on a parser instance.
Common situations: Custom input plugins copying feature-detection code from other plugin helper families; typos when mirroring in_exec's dispatch pattern (case @parser.implement?(:parse_io) when ... else parse); fluentd version skew where a third-party plugin probes features added later.
Related errors
- tag must be a String: #{tag.class}
- time must be a Fluent::EventTime (or Integer): #{time.class}
- record must be a Hash: #{record.class}
- Implement this method in child class
- Optional API #parse_io is not implemented
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/1a504ecc5cb3d290.
Report an issue: GitHub.