elastic/elasticsearch · error · ClassCastException

Cannot apply [&] operation to type [float]

Error message

Cannot apply [&] operation to type [float]

What it means

Thrown by DefMath.and(float, float) which unconditionally throws. When both operands are statically typed float, binary promotion yields float.class and the compiler dispatches to this overload. Bitwise AND is only defined for integral types and booleans in Java; Painless mirrors this restriction by providing a float overload that always fails, keeping the method table complete.

Source

Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java:903

        } else if (o instanceof Character) {
            return (char) o;
        } else {
            throw new ClassCastException("Cannot convert [" + o.getClass().getCanonicalName() + "] to an integral value.");
        }
    }

    // bitwise operators: valid only for integral types

    private static int and(int a, int b) {
        return a & b;
    }

    private static long and(long a, long b) {
        return a & b;
    }

    private static float and(float a, float b) {
        throw new ClassCastException("Cannot apply [&] operation to type [float]");
    }

    private static double and(double a, double b) {
        throw new ClassCastException("Cannot apply [&] operation to type [float]");
    }

    private static boolean and(boolean a, boolean b) {
        return a & b;
    }

    private static Object and(Object left, Object right) {
        if (left instanceof Boolean && right instanceof Boolean) {
            return (boolean) left & (boolean) right;
        } else if (left instanceof Long || right instanceof Long) {
            return longIntegralValue(left) & longIntegralValue(right);
        } else {
            return intIntegralValue(left) & intIntegralValue(right);
        }

View on GitHub (pinned to db6a809a66)

Solutions

  1. Cast both float operands to int before applying &: int ia = (int) a; int ib = (int) b; int result = ia & ib;
  2. Change the field type from float to integer or long if bitmask logic is the intended use case
  3. Use conditional logic instead of bitwise masks for float-valued conditions

Example fix

// before
float a = doc['x'].value;
float b = doc['y'].value;
float result = a & b;

// after
int ia = (int) doc['x'].value;
int ib = (int) doc['y'].value;
int result = ia & ib;
Defensive patterns

Strategy: type-guard

Validate before calling

// Before bitwise AND on float, cast to int
float a = doc['x'].value;
float b = doc['y'].value;
int ia = (int) a;
int ib = (int) b;
return ia & ib;

Type guard

// Check that the value is not float before bitwise AND
boolean isNotFloatingPoint(Object v) {
  return !(v instanceof Float) && !(v instanceof Double);
}

Prevention

When it happens

Trigger: A Painless script applies the & operator to two operands both statically typed as float. The promote() method returns float.class for (float, float), selecting the and(float, float) overload which always throws.

Common situations: Bitwise mask logic on a field explicitly mapped as float; two float variables used in a bitmask expression; refactoring integer bitmask code to operate on float fields without changing the operator; float-typed runtime field used in a flag/mask computation.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/54da15bd7aeb589c. Report an issue: GitHub.