apache/cassandra · error · NumberFormatException

A NaN cannot be converted into a decimal

Error message

A NaN cannot be converted into a decimal

What it means

DecimalType.toBigDecimal converts any Number operand to BigDecimal for arithmetic (add/subtract/multiply/mod, operand selection); Java's BigDecimal cannot represent NaN, so a Number whose doubleValue() is NaN triggers this NumberFormatException.

Solutions

  1. Validate operands with Double.isNaN(d) before the arithmetic call
  2. Replace NaN with null (or a sentinel) rather than passing it to decimal operations
  3. Fix the upstream calculation that produces NaN

Example fix

// before
decimalType.add(left, right); // left may be NaN
// after
if (!Double.isNaN(left.doubleValue()) && !Double.isNaN(right.doubleValue()))
    decimalType.add(left, right);
Defensive patterns

Strategy: type-guard

Validate before calling

if (Double.isNaN(x.doubleValue()) || Double.isNaN(y.doubleValue())) throw new IllegalArgumentException("NaN operand not allowed in decimal arithmetic");

Type guard

boolean isFiniteNumber(Number n) { double d = n.doubleValue(); return !Double.isNaN(d) && !Double.isInfinite(d); }

Try / catch

try { return DecimalType.instance.add(l, r); } catch (NumberFormatException e) { if (e.getMessage().contains("NaN")) { /* handle non-finite operand */ } throw e; }

Prevention

When it happens

Trigger: Calling DecimalType.add/substract/multiply/mod/leftOperand/rightOperand with an operand such as Double.NaN (e.g. computed as 0.0/0.0) reaching toBigDecimal.

Common situations: Floating-point computations upstream producing NaN stored in a double column then mixed with decimal arithmetic; JSON input containing NaN tokens.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/db/marshal/DecimalType.java:352

    /**
     * Converts the specified number into a {@link BigDecimal}.
     *
     * @param number the value to convert
     * @return the converted value
     */
    protected BigDecimal toBigDecimal(Number number)
    {
        if (number instanceof BigDecimal)
            return (BigDecimal) number;

        if (number instanceof BigInteger)
            return new BigDecimal((BigInteger) number);

        double d = number.doubleValue();

        if (Double.isNaN(d))
            throw new NumberFormatException("A NaN cannot be converted into a decimal");

        if (Double.isInfinite(d))
            throw new NumberFormatException("An infinite number cannot be converted into a decimal");

        return BigDecimal.valueOf(d);
    }

    @Override
    public ByteBuffer add(Number left, Number right)
    {
        return decompose(toBigDecimal(left).add(toBigDecimal(right), MAX_PRECISION));
    }

    @Override
    public ByteBuffer substract(Number left, Number right)
    {
        return decompose(toBigDecimal(left).subtract(toBigDecimal(right), MAX_PRECISION));
    }

View on GitHub (pinned to 88fd0f6a0e)