fluent/fluentd · error · Fluent::TimeParser::TimeParseError

invalid time format: value = #{value}, error_class = #{e.cla

Error message

invalid time format: value = #{value}, error_class = #{e.class.name}, error = #{e.message}

What it means

Fluent::TimeParseError raised by TimeParser#parse (lib/fluent/time.rb:281) when the inner strptime/EventTime parse lambda raises for a String input. The message embeds the original value, error class and message, e.g. strptime failing because the text does not match the configured time_format. It is the generic 'string did not match format' error for string time parsing.

Source

Thrown at lib/fluent/time.rb:281

               else ->(v){ Fluent::EventTime.parse(v) }
               end
    end

    # TODO: new cache mechanism using format string
    def parse(value)
      unless value.is_a?(String)
        raise TimeParseError, "value must be string: #{value}"
      end

      if @cache1_key == value
        return @cache1_time
      elsif @cache2_key == value
        return @cache2_time
      else
        begin
          time = @parse.call(value)
        rescue => e
          raise TimeParseError, "invalid time format: value = #{value}, error_class = #{e.class.name}, error = #{e.message}"
        end
        @cache1_key = @cache2_key
        @cache1_time = @cache2_time
        @cache2_key = value
        @cache2_time = time
        return time
      end
    end
    alias :call :parse
  end

  class NumericTimeParser < TimeParser # to include TimeParseError
    def initialize(type, localtime = nil, timezone = nil)
      @cache1_key = @cache1_time = @cache2_key = @cache2_time = nil

      if type == :unixtime
        define_singleton_method(:parse, method(:parse_unixtime))
        define_singleton_method(:call, method(:parse_unixtime))

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Log one failing value and match time_format exactly to it (test in irb: require 'time'; Time.strptime('value', 'format'))
  2. If formats genuinely vary, switch to time_type mixed with time_format_fallbacks listing each known format
  3. Catch upstream format drift: alert on parser errors, or route unparsable records to a dead-letter tag using a filter/parser's rescue logic instead of dropping

Example fix

# before
<parse>
  @type apache2
  time_format %Y-%m-%dT%H:%M:%S%z   # logs actually look like: 20/Aug/2021:12:00:00 +0900
</parse>

# after
<parse>
  @type apache2
  time_format %d/%b/%Y:%H:%M:%S %z
</parse>
Defensive patterns

Strategy: try-catch

Validate before calling

# smoke-test the format against a real sample before startup:
require 'time'
sample = '20/Aug/2021:12:00:00 +0900'
fmt = '%d/%b/%Y:%H:%M:%S %z'
Time.strptime(sample, fmt)   # raises ArgumentError if mismatched — fix config before deploy

Try / catch

begin
  time = parser.parse(str)
rescue Fluent::TimeParseError => e
  # quarantine instead of crash-looping
  router.emit_stream('app.unparsable', MultiEventStream.new(...))
end

Prevention

When it happens

Trigger: A record whose time_key string does not match the configured time_format ('2021/08/20 12:00:00' against %Y-%m-%dT%H:%M:%S%z); a format with %z receiving a timestamp without offset; locales/AM-PM mismatches; calling Fluent::TimeParser.new('%Y-%m-%d').parse('not a date').

Common situations: Application changes its log timestamp format after a release; multiple services with different formats shipped to one parser tag; DST/zone abbreviation (%Z) edge cases strptime rejects; copy-pasted time_format missing the %z the data contains.

Related errors


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