ValueError: could not convert string to float (tested fix)
ValueError: could not convert string to float means float() got text that isn't a plain number, most often an empty string, a thousands comma or a currency sign. We tested 11 inputs in Python 3.13 and the fixes for each.
1. What float() accepts, and what it rejects
The error message quotes the exact string, so read it with repr() in mind. Empty strings, thousands separators, decimal commas, currency and percent signs all fail:
for s in ["", "1,234.5", "3,14", "$9.99", "12%", "1.2.3", "abc", " 2.5\n", "1e3", "nan", "١٢٫٥"]:
try:
print(f"{s!r:12} -> {float(s)!r}")
except ValueError as e:
print(f"{s!r:12} ValueError: {e}")
Output:
'' ValueError: could not convert string to float: ''
'1,234.5' ValueError: could not convert string to float: '1,234.5'
'3,14' ValueError: could not convert string to float: '3,14'
'$9.99' ValueError: could not convert string to float: '$9.99'
'12%' ValueError: could not convert string to float: '12%'
'1.2.3' ValueError: could not convert string to float: '1.2.3'
'abc' ValueError: could not convert string to float: 'abc'
' 2.5\n' -> 2.5
'1e3' -> 1000.0
'nan' -> nan
'١٢٫٥' ValueError: could not convert string to float: '١٢٫٥'
Surrounding whitespace and newlines are fine, and so are 1e3 and nan. The last line uses the Arabic decimal separator ٫. We checked that Arabic-Indic digits with a plain . do parse (float('١٢.٥') gives 12.5).
2. The fix: clean the string first
def to_float(s):
s = s.strip().replace(",", "").lstrip("$").rstrip("%")
return float(s) if s else None
for s in ["1,234.5", "$9.99", "12%", "", " 7 "]:
print(repr(s), "->", to_float(s))
print(float("3,14".replace(",", "."))) # comma as decimal separator
Output:
'1,234.5' -> 1234.5
'$9.99' -> 9.99
'12%' -> 12.0
'' -> None
' 7 ' -> 7.0
3.14
Pick one rule per data source. replace(",", "") is right for 1,234.5 but turns European 3,14 into 314, so only replace a comma with a dot when you know the input uses decimal commas. For locale-aware parsing, use locale.atof() with the right locale set.
3. CSV and API data: skip bad values instead of crashing
import csv, io
data = "price\n9.99\n\n12.50\nN/A\n"
for row in csv.DictReader(io.StringIO(data)):
try:
print(float(row["price"]))
except ValueError as e:
print("skipped:", e)
Output:
9.99
12.5
skipped: could not convert string to float: 'N/A'
csv.DictReader skips the fully blank line, so here the only failure is the N/A placeholder. Catch ValueError per value and log what you skipped.
4. Special values that do parse
for s in ["inf", "-Infinity", "nan", "1_000.5", "0x1A"]:
try:
print(f"{s!r:12} -> {float(s)!r}")
except ValueError as e:
print(f"{s!r:12} ValueError: {e}")
import math
x = float("nan")
print(x == x, math.isnan(x))
Output:
'inf' -> inf
'-Infinity' -> -inf
'nan' -> nan
'1_000.5' -> 1000.5
'0x1A' ValueError: could not convert string to float: '0x1A'
False True
inf, nan and underscores are accepted, which can let bad data through silently. NaN is not equal to itself, so test it with math.isnan(). Hex strings need float.fromhex() or int(s, 16). For the int version of this error, see invalid literal for int() with base 10.
Frequently asked questions
How do I fix could not convert string to float: ''?
The string is empty, often a blank CSV cell or an input() with nothing typed. Check if s.strip(): before converting, or use a default.
How do I convert '1,234.56' to a float?
Remove the thousands separator first: float(s.replace(',', '')). For decimal commas like '3,14', replace ',' with '.' instead.
Does float() accept spaces and newlines?
Yes. Leading and trailing whitespace, including a trailing newline, is ignored.
Written with AI assistance. Measured on 2026-10-22 on Debian with Python 3.13.5: float() on empty, comma, currency, percent, malformed and non-ASCII strings; a cleaning function; csv.DictReader with bad rows; inf/nan/underscore/hex. Every block was run verbatim and its output pasted unedited. PlainHeaders is our extension; Python is free.