{"record":{"id":"b11d9f57158d72d6","repo":"fluent/fluentd","slug":"duplicate-key-e-key","errorCode":null,"errorMessage":"Duplicate key: #{e.key}","messagePattern":"Duplicate key: #(.+?)","errorType":"validation","errorClass":"Fluent::ConfigError","httpStatus":null,"severity":"error","filePath":"lib/fluent/plugin/filter_grep.rb","lineNumber":116,"sourceCode":"        key, regexp = conf[\"regexp#{i}\"].split(/ /, 2)\n        raise Fluent::ConfigError, \"regexp#{i} does not contain 2 parameters\" unless regexp\n        raise Fluent::ConfigError, \"regexp#{i} contains a duplicated key, #{key}\" if regexp_and_conditions[key]\n        regexp_and_conditions[key] = Expression.new(record_accessor_create(key), Regexp.compile(regexp))\n      end\n\n      (1..REGEXP_MAX_NUM).each do |i|\n        next unless conf[\"exclude#{i}\"]\n        key, exclude = conf[\"exclude#{i}\"].split(/ /, 2)\n        raise Fluent::ConfigError, \"exclude#{i} does not contain 2 parameters\" unless exclude\n        raise Fluent::ConfigError, \"exclude#{i} contains a duplicated key, #{key}\" if exclude_or_conditions[key]\n        exclude_or_conditions[key] = Expression.new(record_accessor_create(key), Regexp.compile(exclude))\n      end\n\n      if @regexps.size > 1\n        log.info \"Top level multiple <regexp> is interpreted as 'and' condition\"\n      end\n      @regexps.each do |e|\n        raise Fluent::ConfigError, \"Duplicate key: #{e.key}\" if regexp_and_conditions.key?(e.key)\n        regexp_and_conditions[e.key] = Expression.new(record_accessor_create(e.key), e.pattern)\n      end\n\n      if @excludes.size > 1\n        log.info \"Top level multiple <exclude> is interpreted as 'or' condition\"\n      end\n      @excludes.each do |e|\n        raise Fluent::ConfigError, \"Duplicate key: #{e.key}\" if exclude_or_conditions.key?(e.key)\n        exclude_or_conditions[e.key] = Expression.new(record_accessor_create(e.key), e.pattern)\n      end\n\n      @and_conditions.each do |and_condition|\n        if !and_condition.regexps.empty? && !and_condition.excludes.empty?\n          raise Fluent::ConfigError, \"Do not specify both <regexp> and <exclude> in <and>\"\n        end\n        and_condition.regexps.each do |e|\n          raise Fluent::ConfigError, \"Duplicate key in <and>: #{e.key}\" if regexp_and_conditions.key?(e.key)\n          regexp_and_conditions[e.key] = Expression.new(record_accessor_create(e.key), e.pattern)","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/fluent/fluentd/blob/dd45c6e18dc7be33b5e5a0f0767bf46307ff5626/lib/fluent/plugin/filter_grep.rb#L98-L134","documentation":"After the deprecated regexpN lines are parsed, configure folds in the modern <regexp> section directives, checking each against the regexp_and_conditions hash. If a <regexp> section's key equals a key already supplied via regexpN (or via an earlier duplicate section fold-in), configure raises Fluent::ConfigError 'Duplicate key'.","triggerScenarios":"A config mixing old and new syntax on the same field, e.g. regexp1 message /a/ together with <regexp> key message ... </regexp>; both register the key 'message' in the AND-condition map.","commonSituations":"Incremental migration where the new <regexp> section was added but the old regexpN line was left in place; config management tools merging old and new stanzas.","solutions":["Delete the deprecated regexpN line for that key, keeping the <regexp> section","Or remove the <regexp> section if the old line is intentional (then plan migration)","Grep the config for the duplicated field name to find both occurrences","Validate with fluentd --dry-run"],"exampleFix":"# before\n<filter app.**>\n  @type grep\n  regexp1 message /error/\n  <regexp>\n    key message\n    pattern /fatal/\n  </regexp>\n</filter>\n\n# after\n<filter app.**>\n  @type grep\n  <regexp>\n    key message\n    pattern /error/\n  </regexp>\n  <regexp>\n    key message\n    pattern /fatal/\n  </regexp>\n</filter>","handlingStrategy":"validation","validationCode":"old_keys = (1..20).filter_map { |i| conf[\"regexp#{i}\"]&.split(/ /, 2)&.first }\nnew_keys = grep_filter_conf.sections(:regexp).map { |s| s['key'] }\noverlap = old_keys & new_keys\nabort \"field(s) declared in both regexpN and <regexp>: #{overlap.join(', ')}\" unless overlap.empty?","typeGuard":null,"tryCatchPattern":"begin\n  filter.configure(conf)\nrescue Fluent::ConfigError => e\n  abort \"grep key collision: #{e.message}\" if e.message.start_with?('Duplicate key:')\n  raise\nend","preventionTips":["Finish migration in one commit: remove regexpN lines when adding <regexp> sections","Lint configs for mixed old/new grep syntax","Unique keys across all AND-condition sources","CI dry-run"],"tags":["fluentd","grep-filter","duplicate-key","configuration","migration","configerror"],"backgroundTag":"duplicate-config-key","analyzedSha":"dd45c6e18dc7be33b5e5a0f0767bf46307ff5626","analyzedAt":"2026-08-21T16:22:07.332Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}