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
- Take the exact failing value from the message and add a matching format to time_format_fallbacks (verify with Time.strptime in irb)
- For epoch-numeric fields ensure 'unixtime' or 'float' is in the fallbacks so NumericTimeParser gets tried
- Drop or reroute records with missing/blank time fields before the parser (grep/record_accessor filter) instead of relying on mixed to absorb them
- 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
- Track every timestamp format producers emit and mirror them in time_format_fallbacks
- Dry-run new formats in irb with Time.strptime before adding to config
- Quarantine unparsable records to a dead-letter tag instead of letting errors propagate
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
- time_type is :mixed but time_format and time_format_fallback
- invalid time format: value = #{value}, error_class = #{e.cla
- value must be string: #{value}
- value must be a string or a number: #{value}(#{value.class})
- buffer space has too many data
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/3b075508b80c8f95.
Report an issue: GitHub.