fluent/fluentd · error · Fluent::ConfigError

invalid match - regex

Error message

invalid match - regex

What it means

In <match PATTERN>, a pattern starting with '/' switches GlobMatchPattern into regex mode, where the value must also end with '/' so the content between the slashes becomes an anchored regex (\A...\Z wrapped). A leading '/' without a trailing '/' raises this ConfigError at config setup. This rule exists because tags may contain regex metacharacters, so globs and regexes are disambiguated by the slash delimiters.

Solutions

  1. Close the delimited regex: <match /app\.log/>
  2. If glob semantics are wanted and the tag does not start with '/', use a plain glob like app.*
  3. For tags that genuinely start with '/', match them with an explicit regex: <match /\/var\/log\/.*/>
  4. Remember the regex is fully anchored; write ^/$ anchors are unnecessary

Example fix

# before
<match /app.log>
  @type stdout
</match>

# after
<match /app\.log/>
  @type stdout
</match>
Defensive patterns

Strategy: validation

Validate before calling

pat = '/app\.log/'
raise ArgumentError, 'regex match pattern must end with /' if pat.start_with?('/') && !pat.end_with?('/')
# also accepts /pat/i, /pat/m
Regexp.new('\\A' + pat[1..-2].gsub(/([im])\z/, '') + '\\Z') rescue raise ArgumentError, 'bad match regex'

Prevention

When it happens

Trigger: <match /app.log> (forgot the closing slash); <match /var/log/*> intending a glob for slash-prefixed syslog-style tags; a regex copied from Ruby source (where no delimiters are used) into <match> without wrapping slashes.

Common situations: Writing regex tag matches by hand; tags that begin with '/' (syslog, some container log drivers) colliding with delimiter syntax; mixing up glob '*' semantics (matches dots too, unlike shell globs) and switching to regex mid-edit.

Related errors


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

Appendix: source

Thrown at lib/fluent/match.rb:41

        GlobMatchPattern.new(str)
      end
    end
  end

  class AllMatchPattern < MatchPattern
    def match(str)
      true
    end
  end

  class GlobMatchPattern < MatchPattern
    def initialize(pat)
      if pat.start_with?('/')
        if pat.end_with?('/')
          @regex = Regexp.new("\\A"+pat[1..-2]+"\\Z")
          return
        else
          raise Fluent::ConfigError,  "invalid match - regex"
        end
      end

      stack = []
      regex = ['']
      escape = false
      dot = false

      i = 0
      while i < pat.length
        c = pat[i,1]

        if escape
          regex.last << Regexp.escape(c)
          escape = false
          i += 1
          next

View on GitHub (pinned to dd45c6e18d)