fluent/fluentd · error · Fluent::TimeParser::TimeParseError
value must be string: #{value}
Error message
value must be string: #{value} What it means
Fluent::TimeParseError raised by TimeParser#parse (lib/fluent/time.rb:270) when the value passed is not a Ruby String. StringTimeParser (and strptime) can only handle strings, so an Integer, Float, Hash, or nil arriving at parse() is a hard type error, distinct from an unparseable-but-string value which produces 'invalid time format' instead.
Source
Thrown at lib/fluent/time.rb:270
else
->(v) { t = strptime.exec(v); Fluent::EventTime.new(t.to_i + t.utc_offset - utc_offset, t.nsec) }
end
when format then
if utc_offset.nil?
->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i, t.nsec) }
elsif utc_offset.respond_to?(:call)
->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i + t.utc_offset - utc_offset.call(t), t.nsec) }
else
->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i + t.utc_offset - utc_offset, t.nsec) }
end
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
endView on GitHub (pinned to dd45c6e18d)
Solutions
- If timestamps may be numeric, set time_type float or unixtime (NumericTimeParser accepts String and Numeric), or time_type mixed with unixtime in the fallbacks
- Normalize the record before parsing: convert the field with value.to_s (or skip when nil) in a record_transformer/filter or custom parser
- Ensure the time_key actually exists and is a string in the incoming records (fix the producer or an upstream parser)
Example fix
# before <parse> @type json time_key time # producer now sends "time": 1629489132 (integer) -> TimeParseError </parse> # after <parse> @type json time_key time time_type mixed time_format_fallbacks unixtime, %iso8601 </parse>
Defensive patterns
Strategy: type-guard
Validate before calling
value = record['time'] next unless value.is_a?(String) # skip or convert non-strings before parsing
Type guard
def parsable_string?(v) v.is_a?(String) && !v.empty? end raise Fluent::TimeParseError unless parsable_string?(value)
Try / catch
begin time = parser.parse(value) rescue Fluent::TimeParseError => e log.warn 'skipping record with non-string time', value: value.inspect, error: e.message next # or re-tag to a dead-letter stream end
Prevention
- Pin down the upstream contract: time field is always a string in the documented format
- For numeric epochs configure time_type float/unixtime or mixed instead of the default string parser
- Add a filter that drops/default-converts records whose time_key is nil or non-scalar
When it happens
Trigger: Calling parser.parse(1629489132) or parser.parse(nil) on a Fluent::TimeParser configured for string formats; feeding a JSON payload where the time field is a JSON number into a parser built from time_type :string (the default) — e.g. in_http with record time as epoch integer and no time_type float/unixtime/mixed setting.
Common situations: Upstream producer changes a log field from string timestamp to epoch integer; a filter mutates the time field to a number before the parser runs; nil time field when a record lacks the time_key; using a parser plugin API directly with non-string input.
Related errors
- value must be a string or a number: #{value}(#{value.class})
- 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/902c7628c9235996.
Report an issue: GitHub.