boto/boto3 · error · TypeError

Infinity and NaN not supported

Error message

Infinity and NaN not supported

What it means

Raised by TypeSerializer._serialize_n after converting a number to a Decimal via DYNAMODB_CONTEXT.create_decimal(value). If the resulting decimal stringifies to 'Infinity' or 'NaN' (e.g. Decimal('Infinity'), Decimal('NaN'), or an operation that overflows), the serializer refuses it because DynamoDB does not support Infinity or NaN numeric values.

Source

Thrown at boto3/dynamodb/types.py:216

        if isinstance(value, collections_abc.Mapping):
            return True
        return False

    def _is_listlike(self, value):
        if isinstance(value, (list, tuple)):
            return True
        return False

    def _serialize_null(self, value):
        return True

    def _serialize_bool(self, value):
        return value

    def _serialize_n(self, value):
        number = str(DYNAMODB_CONTEXT.create_decimal(value))
        if number in ['Infinity', 'NaN']:
            raise TypeError('Infinity and NaN not supported')
        return number

    def _serialize_s(self, value):
        return value

    def _serialize_b(self, value):
        if isinstance(value, Binary):
            value = value.value
        return value

    def _serialize_ss(self, value):
        return [self._serialize_s(s) for s in value]

    def _serialize_ns(self, value):
        return [self._serialize_n(n) for n in value]

    def _serialize_bs(self, value):
        return [self._serialize_b(b) for b in value]

View on GitHub (pinned to c7b4afac23)

Solutions

  1. Filter out Infinity/NaN before writing: if value.is_finite(): ....
  2. Replace non-finite values with None or a sentinel Decimal.
  3. Validate upstream data to prevent NaN/Infinity from reaching DynamoDB.

Example fix

# before
from decimal import Decimal
table.put_item(Item={'ratio': Decimal('Infinity')})

# after
from decimal import Decimal
val = Decimal('Infinity')
val = val if val.is_finite() else None
table.put_item(Item={'ratio': val})
Defensive patterns

Strategy: validation

Validate before calling

from decimal import Decimal

def safe_decimal(value):
    d = Decimal(value) if not isinstance(value, Decimal) else value
    if not d.is_finite():
        raise ValueError(f'Non-finite decimal not allowed: {d}')
    return d

def normalize_numbers(item):
    return {k: (safe_decimal(v) if isinstance(v, Decimal) else v) for k, v in item.items()}

Type guard

from decimal import Decimal

def is_finite_decimal(v) -> bool:
    return isinstance(v, Decimal) and v.is_finite()

Prevention

When it happens

Trigger: table.put_item(Item={'x': Decimal('Infinity')}) or Decimal('NaN'). Also computing a division that yields Infinity under the DYNAMODB_CONTEXT (which traps Overflow), or passing Decimal('Inf').

Common situations: Aggregations that divide by zero producing Infinity; ingesting data from sources that emit NaN; using Decimal arithmetic with special values.

Related errors


AI-assisted analysis of boto/boto3@c7b4afac23 (2026-08-04). Data as JSON: /data/errors/c6acedf2576d2cf6.json. Report an issue: GitHub.