fluent/fluentd · error · Fluent::ConfigError

both of utc and localtime are specified, use only one of the

Error message

both of utc and localtime are specified, use only one of them

What it means

Raised as Fluent::ConfigError by FormatterUtils.convert_formatter_conf, which translates old-style formatter/output options (include_time_key, time_as_epoch, localtime, utc, ...) into v1 inject parameters for v0.12-compat plugins. The check is on key presence, not values: if the conf contains BOTH 'localtime' and 'utc' keys it raises immediately, because 'utc' maps to localtime=false and the two contradict each other.

Source

Thrown at lib/fluent/compat/formatter_utils.rb:52

        inject_params = {}
        INJECT_PARAMS.each do |older, newer|
          next unless newer
          if conf.has_key?(older)
            inject_params[newer] = conf[older]
          end
        end

        if conf.has_key?('include_time_key') && Fluent::Config.bool_value(conf['include_time_key'])
          inject_params['time_key'] ||= 'time'
          inject_params['time_type'] ||= 'string'
        end
        if conf.has_key?('time_as_epoch') && Fluent::Config.bool_value(conf['time_as_epoch'])
          inject_params['time_type'] = 'unixtime'
        end
        if conf.has_key?('localtime') || conf.has_key?('utc')
          if conf.has_key?('localtime') && conf.has_key?('utc')
            raise Fluent::ConfigError, "both of utc and localtime are specified, use only one of them"
          elsif conf.has_key?('localtime')
            inject_params['localtime'] = Fluent::Config.bool_value(conf['localtime'])
          elsif conf.has_key?('utc')
            inject_params['localtime'] = !(Fluent::Config.bool_value(conf['utc']))
            # Specifying "localtime false" means using UTC in TimeFormatter
            # And specifying "utc" is different from specifying "timezone +0000"(it's not always UTC).
            # There are difference between "Z" and "+0000" in timezone formatting.
            # TODO: add kwargs to TimeFormatter to specify "using localtime", "using UTC" or "using specified timezone" in more explicit way
          end
        end

        if conf.has_key?('include_tag_key') && Fluent::Config.bool_value(conf['include_tag_key'])
          inject_params['tag_key'] ||= 'tag'
        end

        unless inject_params.empty?
          conf.elements << Fluent::Config::Element.new('inject', '', inject_params, [])
        end

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Keep exactly one of the two keys in that section
  2. For UTC use 'utc true' alone (or 'timezone UTC'); for local time use 'localtime true' or omit both
  3. Audit generated configs for simultaneous localtime/utc keys before deploy

Example fix

# before
<match app.**>
  @type legacy_compat_output
  utc true
  localtime false
</match>

# after
<match app.**>
  @type legacy_compat_output
  utc true
</match>
Defensive patterns

Strategy: validation

Validate before calling

if conf.has_key?('localtime') && conf.has_key?('utc')
  abort 'config sets both localtime and utc - keep exactly one'
end

Prevention

When it happens

Trigger: A section containing 'localtime true' together with 'utc true'; even 'localtime false' + 'utc false' raises because both keys exist; configs assembled by merging snippets where each side contributed one of the flags.

Common situations: Copying a time-formatting block from docs into a config that already set localtime; templating systems merging user overrides with defaults; v0.12-era configs where both flags were historically tolerated.

Related errors


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