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

    type: bugA code related bug.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions