Skip to content

Panic: user-provided comparison function does not correctly implement a total order #23477

@golfdish

Description

@golfdish

A note for the community

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Problem

Starting in 0.43, Vector panics on encountering certain distribution metric data samples, in this instance when writing to a prometheus_remote_write sink:

thread 'vector-worker' panicked at library/core/src/slice/sort/shared/smallsort.rs:865:5:
user-provided comparison function does not correctly implement a total order
stack backtrace:
   0: rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::slice::sort::shared::smallsort::panic_on_ord_violation
   3: core::slice::sort::unstable::quicksort::quicksort
   4: vector::sinks::util::statistic::DistributionStatistic::from_samples
   5: <vector::sinks::prometheus::remote_write::request_builder::RemoteWriteEncoder as vector::sinks::util::encoding::Encoder<alloc::vec::Vec<vector_core::event::metric::Metric>>>::encode_input
   6: vector::sinks::util::builder::SinkBuilderExt::request_builder::{{closure}}::{{closure}}
   7: tokio::runtime::task::raw::poll
   8: tokio::runtime::scheduler::multi_thread::worker::Context::run_task
   9: tokio::runtime::task::raw::poll

I believe this is because release 0.43.0 updated the underlying Rust version from 1.80 to 1.81:

Rust 1.81 introduced the following backwards-incompatible breaking change to how user-provided sorting functions are handled:

As we can see in the current code, the sorting function passed into Vec::sort_unstable_by in statistic.rs is:

                bins.sort_unstable_by(|a, b| {
                    a.value.partial_cmp(&b.value).unwrap_or(Ordering::Equal)
                });

Per the docs, partial_cmp implements a partial order on a type, which is insufficient for functions passed into sort_unstable_by as of Rust 1.81. Per the current docs,

If the comparison function compare does not implement a total order, the function may panic

Unfortunately I haven't yet been able to capture any payloads that look like a smoking gun for triggering this panic, and have no way of reliably reproducing it.

Configuration

sinks:
    mimir:
      type: prometheus_remote_write
      inputs:
        - vector_public_metrics_statsd_mimir_safe
        - vector_public_metrics_routed.prometheus
      endpoint: "http://mimir-nginx.o11y.svc:80/api/v1/push"
      healthcheck:
        enabled: false
      buffer:
        type: disk
        max_size: 1073741824
        when_full: drop_newest
      request:
        retry_attempts: 1
        retry_max_duration_seconds: 3

Version

vector 0.47.0 (x86_64-unknown-linux-musl 3d5af22 2025-05-20 13:53:41.638057046)

Debug Output


Example Data

No response

Additional Context

No response

References

  1. chore(deps): Bump Rust version to 1.81.0 #21509
  2. Improve Ord violation help rust-lang/rust#128273
  3. New panics from sort detecting Ord/PartialOrd violations rust-lang/rust#129561

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions