apache/cassandra · warning · IllegalStateException

Object maps to a buffer that already exists in the set

Error message

Object ${o} maps to a buffer that already exists in the set

What it means

When converting a Set to ByteBuffers in objectToBytes, two distinct elements producing identical serialized buffers would silently collapse; the code detects this and throws IllegalStateException to preserve set cardinality semantics.

Solutions

  1. Deduplicate elements by their serialized form before building the set
  2. Use a single consistent element type
  3. Fix custom serializers that map distinct objects to the same bytes
  4. Wrap the conversion in a validation step comparing element byte representations

Example fix

// before
Set<Object> s = new HashSet<>(Arrays.asList(1, 1L)); // both -> same buffer
// after
Set<Object> s = new HashSet<>(Collections.singletonList(1L));
Defensive patterns

Strategy: validation

Validate before calling

// detect byte-colliding set elements before conversion
Set<ByteBuffer> seen = new HashSet<>();
for (Object o : set) {
    if (!seen.add(ByteBufferUtil.objectToBytes(o).duplicate()))
        throw new IllegalArgumentException("elements collide after serialization: " + o);
}

Prevention

When it happens

Trigger: objectToBytes is called on a Set containing two elements whose byte conversions are equal (e.g., Integer 1 and Long 1L, or objects with colliding custom serializers), typically during UDT value decomposition.

Common situations: Mixed-type sets in application code mapped to a UDT; custom codecs producing identical bytes for distinct elements; numerically equal values of different Java types.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/utils/ByteBufferUtil.java:654

            Map<ByteBuffer, ByteBuffer> bbs = new LinkedHashMap<>();
            for (Map.Entry<?, ?> e : map.entrySet())
            {
                Object key = e.getKey();
                ByteBuffer previousValue = bbs.put(objectToBytes(key), objectToBytes(e.getValue()));
                if (previousValue != null)
                    throw new IllegalStateException("Key " + key + " already maps to value " + previousValue);
            }
            // decompose/serializer doesn't use the isMultiCell, so safe to do this
            return MapType.getInstance(BytesType.instance, BytesType.instance, false).decompose(bbs);
        }
        else if (obj instanceof Set)
        {
            Set<?> set = (Set<?>) obj;
            // convert subtypes to BB
            Set<ByteBuffer> bbs = new LinkedHashSet<>();
            for (Object o : set)
                if (!bbs.add(objectToBytes(o)))
                    throw new IllegalStateException("Object " + o + " maps to a buffer that already exists in the set");
            // decompose/serializer doesn't use the isMultiCell, so safe to do this
            return SetType.getInstance(BytesType.instance, false).decompose(bbs);
        }
        else if (obj instanceof Date)
            return TimestampType.instance.decompose((Date) obj);
        else
            throw new IllegalArgumentException(String.format("Cannot convert value %s of type %s",
                                                             obj,
                                                             obj.getClass()));
    }

    public static ByteBuffer bytes(byte b)
    {
        return ByteBuffer.allocate(1).put(0, b);
    }

    public static ByteBuffer bytes(short s)
    {

View on GitHub (pinned to 88fd0f6a0e)