#12491·fluent-bit

in_statsd: timer metrics fall through into the "set" case and produce records with duplicate keys

Author: K-ANOYCreated Sep 30, 2026Updated Sep 30, 2026
Labelsstatus: waiting-for-triage

In the non-metrics (log record) mode of in_statsd, the STATSD_TYPE_TIMER case in statsd_process_message() has no break, so every timer line (name:value|ms) appends a second set of type/bucket/value keys with type = "set" and a string value to the same record.

Details

statsd_process_message():

c
case STATSD_TYPE_TIMER:
    ret = flb_log_event_encoder_append_body_values(
            ctx->log_encoder,
            FLB_LOG_EVENT_CSTRING_VALUE("type"),
            FLB_LOG_EVENT_CSTRING_VALUE("timer"),
            ... "bucket", ..., "value", <double>, "sample_rate", ...);

case STATSD_TYPE_SET:                      /* <- no break above */
    ret = flb_log_event_encoder_append_body_values(
            ctx->log_encoder,
            FLB_LOG_EVENT_CSTRING_VALUE("type"),
            FLB_LOG_EVENT_CSTRING_VALUE("set"),
            ... "bucket", ..., "value", <string>);
    break;

StatsD defines ms as a timing and s as a set; they are distinct metric types.

Trigger / observed result

UDP datagram lat:320|ms to an unmodified build (metrics off, the default). Raw record from the stdout output (issues/verification/fluentbit_inputs/fluent-bit_raw_records.txt):

{"type"=>"timer", "bucket"=>"lat", "value"=>320.000000, "sample_rate"=>1.000000,
 "type"=>"set",   "bucket"=>"lat", "value"=>"320"}

With Format json_lines the duplicate keys collapse to the last occurrence, and the event is emitted as {"sample_rate":1.0,"type":"set","bucket":"lat","value":"320"}, so every timer is reported as a set with a string value.

Expected: {"type":"timer","bucket":"lat","value":320.0,"sample_rate":1.0}.

Impact

Data correctness only: every StatsD timer ingested in log mode is mislabeled (and, after JSON conversion, loses its numeric value type). No memory-safety impact. The metrics on path uses cmetrics' decoder and is not affected by this switch.

Suggested fix

Add break; at the end of the STATSD_TYPE_TIMER case, and add a runtime test for an |ms line.