fluent/fluentd · error · Fluent::ConfigError
Invalid regexp '#{formats}': #{e}
Error message
Invalid regexp '#{formats}': #{e} What it means
MultilineParser#configure (lib/fluent/plugin/parser_multiline.rb:67) joins the format1..formatN regexes and compiles the combined expression; any failure is re-raised as Fluent::ConfigError with the joined source. Two distinct causes land here: the regex body is syntactically invalid (RegexpError from Regexp.new), or the manual 'No named captures' raise fires because the combined regexp has zero named capture groups. Both abort configuration.
Source
Thrown at lib/fluent/plugin/parser_multiline.rb:67
yield(time, record)
m
end
end
def configure(conf)
super
formats = parse_formats(conf).compact.map { |f| f[1..-2] }.join
begin
regexp = Regexp.new(formats, Regexp::MULTILINE)
if regexp.named_captures.empty?
raise "No named captures"
end
regexp_conf = Fluent::Config::Element.new("", "", { "expression" => "/#{formats}/m" }, [])
@parser = Fluent::Plugin::MultilineParser::MultilineRegexpParser.new
@parser.configure(conf + regexp_conf)
rescue => e
raise Fluent::ConfigError, "Invalid regexp '#{formats}': #{e}"
end
if @format_firstline
check_format_regexp(@format_firstline, 'format_firstline')
@firstline_regex = Regexp.new(@format_firstline[1..-2])
end
end
def parse(text, &block)
loop do
m =
if @unmatched_lines
@parser.call(text) do |time, record|
if time && record
yield(time, record)
else
yield(Fluent::EventTime.now, { 'unmatched_line' => text })
endView on GitHub (pinned to dd45c6e18d)
Solutions
- Ensure the combined regex compiles: test with ruby -e "Regexp.new(ARGV.join, Regexp::MULTILINE)" using the stripped bodies.
- Include at least one named capture group like (?<message>.*) across the formatN set.
- Validate the whole config with fluentd --dry-run before deploying.
- Check Ruby (not PCRE/grep) regex syntax: named groups use (?<name>...), and backslashes must survive config parsing.
Example fix
# before
format1 /^\d{4}/ # no named capture -> 'No named captures'
format2 /\s+.*/
# after
format1 /(?<time>^\d{4}-\d{2}-\d{2})/
format2 /(?<message>\s+.*)/ Defensive patterns
Strategy: validation
Validate before calling
# pre-deploy: verify combined multiline regex compiles and has named captures bodies = %w[format1_body format2_body] # paste stripped bodies here joined = bodies.join Regexp.new(joined, Regexp::MULTILINE) abort 'no named captures' if Regexp.new(joined, Regexp::MULTILINE).named_captures.empty?
Prevention
- Always include at least one (?<name>...) group in the formatN set.
- Test each regex in an interactive Ruby shell with Regexp::MULTILINE.
- Dry-run the config after touching format lines.
- Escape for both config parsing and Ruby regex (double backslashes where needed).
When it happens
Trigger: format1 /(?<log>\w+)/ format2 /(?<tail>\s+.*)/ with an unbalanced paren or stray '*' in one of them; multi-line Java stack-trace formats where every formatN uses numbered captures () instead of named (?<x>...); format strings containing raw '/' that breaks the /.../ delimiters after [1..-2] stripping.
Common situations: Configuring in_tail multiline parsing for Java/MySQL log formats; converting old fluentd v0 'format_firstline /.../' recipes to the format1..format20 scheme; escaping errors when porting regexes from other tools (double-escaping \d in config files).
Related errors
- Invalid regexp in #{key}: #{e}
- Jump of format index found. format#{i - 1} is missing.
- Invalid formatN found. N should be 1 - #{FORMAT_MAX_NUM}: #{
- format should be Regexp, need //, in #{key}: '#{format}'
- invalid match - regex
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/dca4328a9535af86.
Report an issue: GitHub.