fluent/fluentd · error · Fluent::ConfigError

No named captures in 'expression' parameter. The regexp must

Error message

No named captures in 'expression' parameter. The regexp must have at least one named capture

What it means

RegexpParser#configure (lib/fluent/plugin/parser_regexp.rb:45) raises Fluent::ConfigError when the compiled expression parameter has no named capture groups. The regexp parser builds each output record from named captures (m.names.each), so without at least one (?<name>...) group there is nothing to extract. Configuration aborts at startup or dry-run.

Source

Thrown at lib/fluent/plugin/parser_regexp.rb:45

      config_param :ignorecase, :bool, default: false, deprecated: "Use /pattern/i instead, this option is no longer effective"
      desc 'Build regular expression as a multline mode'
      config_param :multiline, :bool, default: false, deprecated: "Use /pattern/m instead, this option is no longer effective"

      config_set_default :time_key, 'time'

      def configure(conf)
        super
        # For compat layer
        if @ignorecase || @multiline
          options = 0
          options |= Regexp::IGNORECASE if @ignorecase
          options |= Regexp::MULTILINE if @multiline
          @expression = Regexp.compile(@expression.source, options)
        end
        @regexp = @expression # For backward compatibility

        if @expression.named_captures.empty?
          raise Fluent::ConfigError, "No named captures in 'expression' parameter. The regexp must have at least one named capture"
        end
      end

      def parse(text)
        m = @expression.match(text)
        unless m
          yield nil, nil
          return
        end

        r = {}
        m.names.each do |name|
          if value = m[name]
            r[name] = value
          end
        end

        time, record = convert_values(parse_time(r), r)

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Add at least one named group: expression /(?<message>.*)/.
  2. Convert each meaningful positional group (...) to (?<field>...).
  3. Prefer the multiline formatN style or a grok-like filter when the pattern is complex.
  4. Dry-run the config to catch this without touching production.

Example fix

# before
<parse>
  @type regexp
  expression /^\[ERROR\].*$/
</parse>
# after
<parse>
  @type regexp
  expression /^\[(?<level>ERROR)\](?<message>.*)$/
</parse>
Defensive patterns

Strategy: validation

Validate before calling

expr = Regexp.new('^\\[(?<level>\\w+)\\](?<message>.*)$')
abort 'needs a named capture' if expr.named_captures.empty?

Prevention

When it happens

Trigger: <parse> @type regexp expression /^(?<host>[^ ]*) / works, but expression /^.*$/ or /^\[ERROR\]/ (only positional groups) fails; converting a grok/PCRE pattern with () groups to fluentd regexp syntax without renaming them.

Common situations: Writing in_tail/in_tcp regexp parsers for custom app logs; porting patterns from grep/sed pipelines that use unnamed groups; editing an existing expression and accidentally dropping the named group.

Related errors


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