fluent/fluentd · error · Fluent::ConfigError
invalid regexp: missing right slash: #{str}
Error message
invalid regexp: missing right slash: #{str} What it means
For parameters of the :regexp type, a value starting with '/' is treated as a delimited regex literal: the closing '/' must appear within the last three characters so that at most two flag characters ('i', 'm') may follow it. regexp_value computes the last '/' via rindex and raises this ConfigError when that slash sits too far from the end, i.e. the literal is effectively unterminated. Without a leading slash the whole string is compiled directly as a regex, so only the delimited form has this syntax requirement.
Source
Thrown at lib/fluent/config/types.rb:90
# Current parser passes comment without actual values, e.g. "param #foo".
# parser should pass empty string in this case but changing behaviour may break existing environment so keep parser behaviour. Just ignore comment value in boolean handling for now.
if str.respond_to?(:start_with?) && str.start_with?('#')
true
elsif opts[:strict]
raise Fluent::ConfigError, "#{name}: invalid bool value: #{str}"
else
nil
end
end
end
def self.regexp_value(str, opts = {}, name = nil)
return nil unless str
return Regexp.compile(str) unless str.start_with?("/")
right_slash_position = str.rindex("/")
if right_slash_position < str.size - 3
raise Fluent::ConfigError, "invalid regexp: missing right slash: #{str}"
end
options = str[(right_slash_position + 1)..-1]
option = 0
option |= Regexp::IGNORECASE if options.include?("i")
option |= Regexp::MULTILINE if options.include?("m")
Regexp.compile(str[1...right_slash_position], option)
end
def self.string_value(val, opts = {}, name = nil)
return nil if val.nil?
v = val.to_s
v = v.frozen? ? v.dup : v # config_param can't assume incoming string is mutable
v.force_encoding(Encoding::UTF_8)
end
STRING_TYPE = Proc.new { |val, opts = {}, name = nil|
Config.string_value(val, opts, name)View on GitHub (pinned to dd45c6e18d)
Solutions
- Close the literal: '/app\.log/' or with flags '/app\.log/i'
- If the pattern is not meant to be a delimited regex, drop the leading slash so the raw string is compiled as-is (only flags are then unavailable)
- For tags that genuinely start with '/', write a full delimited regex that matches them, e.g. '/\/var\/log\/.*/'
- Double-check escaping: the content between the slashes is passed to Regexp.compile verbatim
Example fix
# before # config_param :exclude, :regexp <match demo.**> @type stdout exclude /debug </match> # after <match demo.**> @type stdout exclude /debug/ </match>
Defensive patterns
Strategy: validation
Validate before calling
s = raw_value.to_s
terminated = !s.start_with?('/') || (idx = s.rindex('/')) && idx >= s.size - 3
raise ArgumentError, "unterminated regexp literal: #{s.inspect}" unless terminated
Regexp.compile(s[1...s.rindex('/')]) rescue raise ArgumentError, "bad regexp body: #{s.inspect}" Prevention
- Always write delimited regexes as /pattern/ or /pattern/i
- Remember any value starting with '/' is regex mode; use globs without leading slash otherwise
- Test regex params in a --dry-run load before deploying
When it happens
Trigger: config_param :pattern, :regexp with a value like '/app\.log' (opening slash but no closing slash), '/logs?' with no terminator, or a leading-slash tag glob written as '/var/log/*' that is misparsed as an unterminated regex literal.
Common situations: Forgetting the trailing slash in <match>-adjacent regex params; tags that literally start with '/' (syslog-style, some Docker logging drivers) colliding with the delimited-regex syntax; hand-editing configs where the glob was copied from a path.
Related errors
- #{name}: invalid bool value: #{str}
- #{name}: #{e.message}
- Unknown #{@kind} plugin '#{type}'. Run 'gem search -rd fluen
- Missing '@type' parameter on <#{e.name}> directive
- 'format' parameter is required
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/0d98d772540448db.
Report an issue: GitHub.