Skip to content
SQL errors / Fix “Conversion Error: Could Not Convert String” in SQL
SQL error

Fix “Conversion Error: Could Not Convert String” in SQL

A text value won't cast to the type you asked for. The message names the value, the type, and the column.

The exact message
DuckDB
Conversion Error: Could not convert string 'N/A' to INT32 when casting from source column counted
PostgreSQL
invalid input syntax for type integer: "N/A"
SQL Server
Conversion failed when converting the varchar value 'N/A' to data type int.

A cast to decimal reads “Error converting data type varchar to numeric.” instead.

MySQL
Incorrect integer value: 'N/A' for column 'quantity' at row 1

Only when writing to a column in strict mode. CAST('N/A' AS SIGNED) returns 0 with a warning instead of failing.

SQLite
No error - the cast returns 0.

Checked on SQLite 3.53. CAST('N/A' AS INTEGER) is 0, so bad values turn into zeros silently.

The symptom

You turn a text column into a number, a date, or a true/false value, and one row holds something that isn't one: 'N/A', an empty string, '$12.00', '1,250'. DuckDB stops the whole query at the first value it can't convert. It doesn't skip the row or return a NULL.

The bench below is a stock count typed into a spreadsheet, the usual source: two good numbers, a placeholder, and a blank cell.

Read the message

Could not convert string 'N/A' to INT32 when casting from source column counted has three parts, and each one is a clue:

  • The value, 'N/A': the first one DuckDB reached that wouldn't convert. There may be more.
  • The target type, in DuckDB's internal name. The table below translates it.
  • The column, after source column. It's left off when the value is a literal you typed, such as cast('N/A' as integer).
The message says You asked for
INT32 integer, int
INT64 bigint
DOUBLE double, float8
DECIMAL(10,2) decimal(10,2), numeric(10,2)
BOOL boolean
UINT8 Usually an enum type (see below)

The decimal version quotes the value in double quotes instead: Could not convert string "N/A" to DECIMAL(10,2). Same error, same fixes.

The fix

try_cast returns NULL for a value it can't convert instead of failing, so the query finishes and the bad rows show up as gaps:

The query that fails
create or replace table stock_counts as
select * from (values
  ('Fiddle-Leaf Fig', '14'),
  ('Monstera Deliciosa', '40'),
  ('Snake Plant', 'N/A'),
  ('ZZ Plant', '')
) as t(product_name, counted);
select product_name, cast(counted as integer) as quantity
from stock_counts;

Running it raises Could not convert string 'N/A' to INT32 when casting from source column counted.

The corrected query
create or replace table stock_counts as
select * from (values
  ('Fiddle-Leaf Fig', '14'),
  ('Monstera Deliciosa', '40'),
  ('Snake Plant', 'N/A'),
  ('ZZ Plant', '')
) as t(product_name, counted);
select product_name, try_cast(counted as integer) as quantity
from stock_counts
order by product_name;

Open the corrected query in the playground

The Snake Plant and the ZZ Plant come back with a NULL quantity. That keeps the query running, but it hides the problem as well as solving it, so look at what failed before you trust a total.

Find every value that won't convert

The message only shows the first bad value. To list all of them, keep the rows where the text is present but try_cast gives up:

List the values that won't convert
create or replace table stock_counts as
select * from (values
  ('Fiddle-Leaf Fig', '14'),
  ('Monstera Deliciosa', '40'),
  ('Snake Plant', 'N/A'),
  ('ZZ Plant', '')
) as t(product_name, counted);

select product_name, counted
from stock_counts
where counted is not null
  and try_cast(counted as integer) is null
order by product_name;

That returns two rows: 'N/A' and the empty string. The is not null matters: a real NULL casts to NULL without an error, so it isn't one of the values to fix.

Clean the text, then cast

Most failures are formatting, not missing data. Strip what the type can't hold, then cast what's left. Spaces at either end are fine: DuckDB trims them itself.

Strip currency signs and thousands separators
select price_text,
       try_cast(
         replace(replace(price_text, '$', ''), ',', '') as decimal(10,2)
       ) as price
from (values ('32.00'), ('$12.00'), ('1,250.00'), ('N/A')) as t(price_text);

The first three become 32.00, 12.00, and 1250.00. 'N/A' stays NULL, which is right: it was never a price.

Watch out

Some strings convert when you might expect an error. cast('12.50' as integer) is 13: DuckDB rounds a decimal string to the nearest whole number. SQLite truncates the same string to 12. Cast to decimal first if you need to choose how to round.

When you never wrote CAST

Comparing a text column to a number makes DuckDB convert the column for you, and that conversion fails the same way. Garden Shop's coupon_code holds codes like SPRING10:

Wrong: a number compared to a text column
select order_id, coupon_code
from orders
where coupon_code = 10;

DuckDB answers Could not convert string 'SPRING10' to INT32 when casting from source column coupon_code. The same happens with in (1, 2), and with a join that matches a text column to a number column. Compare text with text:

Right: quote the value
select order_id, coupon_code
from orders
where coupon_code = 'SPRING10'
order by order_id;

That returns orders 1, 8, and 19. A > or < comparison fails earlier, with a different message: Cannot compare values of type VARCHAR and type INTEGER_LITERAL - an explicit cast is required.

“to UINT8” means an enum

An enum stores each allowed label as a small number, and the error names that storage type instead of the enum. So Could not convert string 'processing' to UINT8 means 'processing' isn't one of the enum's labels. Ask the enum for its list:

Which labels does the enum allow?
create or replace type order_status as enum ('pending', 'shipped', 'cancelled');

select enum_range(null::order_status) as allowed;
Which values are missing from it?
select distinct status
from orders
where status not in (select unnest(enum_range(null::order_status)));

The second query returns processing, the label the enum forgot. Either add it to the type or map the value before you load it. CREATE TYPE covers changing an enum.

Dates fail with their own message

A date in the wrong layout gives a different conversion error: invalid date field format: "03/15/2024", expected format is (YYYY-MM-DD). Casting only reads YYYY-MM-DD. For anything else, describe the layout with strptime:

Parse a US-style date
select strptime('03/15/2024', '%m/%d/%Y')::date as order_date;

try_strptime is the forgiving version, returning NULL where the text doesn't match the format.

How other engines word it

Engine Message
DuckDB Conversion Error: Could not convert string 'N/A' to INT32 when casting from source column counted
PostgreSQL invalid input syntax for type integer: "N/A"
SQL Server Conversion failed when converting the varchar value 'N/A' to data type int. A cast to decimal reads “Error converting data type varchar to numeric.” instead.
MySQL Incorrect integer value: 'N/A' for column 'quantity' at row 1 Only when writing to a column in strict mode. CAST('N/A' AS SIGNED) returns 0 with a warning instead of failing.
SQLite No error - the cast returns 0. Checked on SQLite 3.53. CAST('N/A' AS INTEGER) is 0, so bad values turn into zeros silently.

SQLite and MySQL's CAST don't raise an error at all: they turn a bad value into 0. That's worse than an error, because a total built on those zeros looks believable.

Related errors

Learn more