apache/cassandra · error · UnsupportedOperationException

You shouldn't wrap the DynamicEndpointSnitch (within itself…

Error message

You shouldn't wrap the DynamicEndpointSnitch (within itself or otherwise)

What it means

DynamicEndpointSnitch (DES) overrides compareEndpoints to deliberately throw UnsupportedOperationException. Its latency scores change constantly, so a comparator over DES would be non-deterministic; wrapping DES inside another snitch (including itself) is unsafe and unsupported, so any comparison call throws.

Solutions

  1. Remove DynamicEndpointSnitch from the snitch wrapper chain — configure the base snitch (e.g. GossipingPropertyFileSnitch) as endpoint_snitch and let dynamic_snitch_options wrap it automatically
  2. Never pass a DES instance as the delegate of another snitch
  3. Use sortByProximityWithScore or the ranking APIs instead of calling compareEndpoints directly in custom code
  4. Upgrade config: in modern Cassandra DES is implicit via dynamic_snitch options; delete explicit DES configuration

Example fix

// before (cassandra.yaml)
endpoint_snitch: DynamicEndpointSnitch
// after
endpoint_snitch: GossipingPropertyFileSnitch
dynamic_snitch_update_interval_in_ms: 100
Defensive patterns

Strategy: type-guard

Validate before calling

IEndpointSnitch snitch = DatabaseDescriptor.getEndpointSnitch();
if (snitch instanceof DynamicEndpointSnitch) throw new IllegalStateException("Do not use DES comparator directly");

Type guard

boolean isDes(IEndpointSnitch s) { return s instanceof DynamicEndpointSnitch; }

Try / catch

try { snitch.compareEndpoints(target, a1, a2); }
catch (UnsupportedOperationException e) { /* use sortByProximity instead */ }

Prevention

When it happens

Trigger: Calling compareEndpoints (or sortByProximity paths that fall back to it) on a snitch instance that is a DynamicEndpointSnitch — which happens only if DES was configured as a delegate/wrapper of another snitch or vice versa.

Common situations: cassandra.yaml misconfigured so endpoint_snitch or the snitch wrapper chain nests DynamicEndpointSnitch (e.g. dynamic_snitch combined incorrectly with a delegated snitch); custom code calling sortByProximity directly on a DES reference.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/f959919a1aa45a0b. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/locator/DynamicEndpointSnitch.java:250

        if (scored2 == null)
        {
            scored2 = defaultStore(a2.endpoint());
        }

        if (scored1.equals(scored2))
            return subCompare.compare(a1, a2);
        if (scored1 < scored2)
            return -1;
        else
            return 1;
    }

    public int compareEndpoints(InetAddressAndPort target, Replica a1, Replica a2)
    {
        // That function is fundamentally unsafe because the scores can change at any time and so the result of that
        // method is not stable for identical arguments. This is why we don't rely on super.sortByProximity() in
        // sortByProximityWithScore().
        throw new UnsupportedOperationException("You shouldn't wrap the DynamicEndpointSnitch (within itself or otherwise)");
    }

    public void receiveTiming(InetAddressAndPort host, long latency, TimeUnit unit) // this is cheap
    {
        ExponentiallyDecayingReservoir sample = samples.get(host);
        if (sample == null)
        {
            ExponentiallyDecayingReservoir maybeNewSample = new ExponentiallyDecayingReservoir(WINDOW_SIZE, ALPHA);
            sample = samples.putIfAbsent(host, maybeNewSample);
            if (sample == null)
                sample = maybeNewSample;
        }
        sample.update(unit.toMillis(latency));
    }

    @VisibleForTesting
    public void updateScores() // this is expensive
    {

View on GitHub (pinned to 88fd0f6a0e)