fluent/fluentd · error · Fluent::TimeParser::TimeParseError
value must be a string or a number: #{value}(#{value.class})
Error message
value must be a string or a number: #{value}(#{value.class}) What it means
Fluent::TimeParseError raised by NumericTimeParser#parse_unixtime (lib/fluent/time.rb:308) when the value is neither a String nor a Numeric — for example a Hash, Array, true/false, or nil. This is the type-gate in front of epoch-seconds parsing; valid Strings are then coerced with to_i, so unparseable-but-numeric-looking strings do not raise here.
Source
Thrown at lib/fluent/time.rb:308
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))
else # :float
define_singleton_method(:parse, method(:parse_float))
define_singleton_method(:call, method(:parse_float))
end
end
def parse_unixtime(value)
unless value.is_a?(String) || value.is_a?(Numeric)
raise TimeParseError, "value must be a string or a number: #{value}(#{value.class})"
end
if @cache1_key == value
return @cache1_time
elsif @cache2_key == value
return @cache2_time
end
begin
time = Fluent::EventTime.new(value.to_i)
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
timeView on GitHub (pinned to dd45c6e18d)
Solutions
- Validate the field exists and is String/Numeric before it reaches the parser (record_filter or custom filter)
- Fix the producer so time is epoch seconds/epoch string, not a structured object or null
- For strings like '2021-08-20T...' use a string time_type with formats instead of unixtime, or mixed with fallbacks
Example fix
# before
<parse>
@type json
time_key time
time_type unixtime # record: {"time": null} -> TimeParseError
</parse>
# after
<parse>
@type json
time_key time
time_type unixtime
estimate_current_event false
</parse>
# plus a filter dropping records without a usable time:
<filter **>
@type record_transformer
remove_keys _dummy_
</filter> Defensive patterns
Strategy: type-guard
Validate before calling
value = record['time'] next unless value.is_a?(String) || value.is_a?(Numeric)
Type guard
def unixtime_like?(v) v.is_a?(String) || v.is_a?(Numeric) end
Try / catch
begin t = numeric_parser.parse(value) rescue Fluent::TimeParseError => e log.warn 'bad time field', value: value.inspect, error: e.message next end
Prevention
- Ensure the producer emits the time field as number or numeric string, never null/object
- Validate records at the edge (in_http / custom parser) and reject malformed ones early
When it happens
Trigger: time_type unixtime configured and a record's time field is a JSON object/array/boolean/null (e.g. {"time": null} or {"time": {"$date": ...}}); calling parser.parse(nil) or parser.parse({}) on a NumericTimeParser built for :unixtime.
Common situations: MongoDB-style extended JSON dates ($date wrapper) arriving as a Hash; producer omits the time field making it nil; a filter replaces the time field with a structured value; API changes turning the field into a nested object.
Related errors
- value must be string: #{value}
- invalid time format: value = #{value}, error_class = #{e.cla
- both of utc and localtime are specified, use only one of the
- specifying timezone requires time format
- invalid time format: value = #{value}, even though fallbacks
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/71b6a248cf3812ee.
Report an issue: GitHub.