Float types are not supported. Use Decimal types instead.
TL;DR — boto3 raised a Python TypeError because you passed a float to DynamoDB. DynamoDB stores numbers as arbitrary-precision decimals (up to 38 digits), and binary floats can't represent those exactly — so boto3 refuses them. Convert to decimal.Decimal before writing, ideally via str() so you don't inherit the float's rounding.
What it means
TypeError: Float types are not supported. Use Decimal types instead.This is a client-side error raised by boto3 (the AWS SDK for Python), not a DynamoDB service response — the SDK's serializer rejects float before the request is ever sent. DynamoDB's N type holds a decimal number with up to 38 digits of precision; Python float is IEEE-754 binary, which can't round-trip those values losslessly. boto3 fails loud rather than silently store an approximation.
Why it happens
- Writing a raw
float— a price30.51, a computed average, ajson.loads()result (JSON numbers with decimals become Python floats). - Nested floats — a float buried inside a dict/list you're putting; boto3 walks the whole structure and rejects the first one.
- Arithmetic results —
total / count,sum(...), or any division that yields a float. - Third-party data (pandas, an API response) that hands you numpy/
float64values.
How to fix it
- Convert to
decimal.Decimalbefore writing:from decimal import Decimal table.put_item(Item={'pk': 'ORDER#1', 'total': Decimal('30.51')}) - Build the
Decimalfrom astr, not the float —Decimal(30.51)inherits the binary-float error (30.510000000000001...);Decimal(str(30.51))gives you exactly30.51. - Convert recursively for nested data — walk the dict/list and turn every float into
Decimal(str(x))beforeput_item. A common pattern isjson.loads(json.dumps(obj), parse_float=Decimal). - Reading back,
Decimalvalues come out asDecimal; convert tofloat/intat the edge of your app if you need native types, and configure the resource's deserializer if you want a specific numeric type. - For values beyond 38 digits of precision (IDs, huge integers), store them as strings instead of numbers — see number overflow.
FAQ
Why doesn't DynamoDB accept Python floats? DynamoDB numbers are arbitrary-precision decimals (up to 38 digits). Python float is IEEE-754 binary and can't represent most decimals exactly, so boto3 refuses to store a lossy approximation and raises "Float types are not supported. Use Decimal types instead."
How do I convert a float to Decimal correctly for DynamoDB? Build the Decimal from the string form: Decimal(str(value)), not Decimal(value). Decimal(30.51) carries the float's binary rounding error, while Decimal(str(30.51)) is exactly 30.51. For nested structures, use json.loads(json.dumps(obj), parse_float=Decimal).
Related errors
- Number overflow — a value beyond DynamoDB's 38-digit magnitude range.
- SerializationException — a number/string wire-type mismatch.
- Learn: DynamoDB data types