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

invalid time format: value = #{value}, even though fallbacks

Error message

invalid time format: value = #{value}, even though fallbacks: #{fallback_class}

What it means

Fluent::TimeParseError raised by MixedTimeParser#parse (lib/fluent/time.rb:511) when the value could not be parsed by ANY of the configured parsers — the primary time_format plus every entry in time_format_fallbacks. The message lists the parser classes that were tried (e.g. Fluent::TimeParser,Fluent::NumericTimeParser), so you can see what 'mixed' actually attempted.

Source

Thrown at lib/fluent/time.rb:511

        end
      end
    end

    def parse(value)
      @parsers.each do |parser|
        begin
          Float(value) if parser.class == Fluent::NumericTimeParser
        rescue
          next
        end
        begin
          return parser.parse(value)
        rescue
          # skip TimeParseError
        end
      end
      fallback_class = @parsers.collect do |parser| parser.class end.join(",")
      raise TimeParseError, "invalid time format: value = #{value}, even though fallbacks: #{fallback_class}"
    end
  end

end

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Take the exact failing value from the message and add a matching format to time_format_fallbacks (verify with Time.strptime in irb)
  2. For epoch-numeric fields ensure 'unixtime' or 'float' is in the fallbacks so NumericTimeParser gets tried
  3. Drop or reroute records with missing/blank time fields before the parser (grep/record_accessor filter) instead of relying on mixed to absorb them
  4. Check the fallback_class list in the message — if it shows fewer parsers than you configured, a fallback name is misspelled and was skipped

Example fix

# before
time_type mixed
time_format %iso8601
time_format_fallbacks unixtime
# value '20/Aug/2021:12:00:00 +0900' fails both

# after
time_type mixed
time_format %iso8601
time_format_fallbacks unixtime, %d/%b/%Y:%H:%M:%S %z
Defensive patterns

Strategy: try-catch

Validate before calling

# verify every candidate value parses with at least one configured format:
require 'time'
formats = ['%iso8601']
fallbacks = ['unixtime']
def parse_ok?(v, formats, fallbacks)
  (formats + fallbacks).any? do |f|
    if %w[unixtime float].include?(f)
      Float(v, exception: false)
    else
      begin; Time.strptime(v, f); true; rescue; false; end
    end
  end
end

Type guard

def mixed_parsable?(value)
  value.is_a?(String) && !value.to_s.empty? && !['null', 'nil'].include?(value.strip)
end

Try / catch

begin
  time = mixed_parser.parse(value)
rescue Fluent::TimeParseError => e
  router.emit('app.unparsable', Fluent::Engine.now, record)  # quarantine
end

Prevention

When it happens

Trigger: time_type mixed with formats like %iso8601 + unixtime, and a record whose time field matches none: '20-Aug-2021 (JST)' or a null-in-a-string 'null', or a non-string value that fails the Float() pre-check for the numeric parsers. Each parser's TimeParseError is swallowed and only this final error surfaces.

Common situations: A new service ships a third timestamp style not yet in the fallbacks list; a locale-format date (DD/MM vs MM/DD ambiguity) not covered; producer sends 'null'/empty string for missing timestamps; fallbacks list has a typo (e.g. %iso8601 misspelled) so nothing can ever match.

Related errors


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