- Result code
- SQLITE_ERROR (1)
- Product
- SQLite library
- Versions
- SQLite 3.x (examples run on 3.39.2; shell output from 3.50.6)
- Category
- Syntax & Query Structure
- Last reviewed
- 24 October 2026
On this page
What it means
SQLite's parser reached a word or symbol that cannot appear at that point of the statement. The quoted token is where parsing stopped, which is often just after the real mistake.
The parser reads the statement from left to right and stops at the first token that does not fit the grammar. The message quotes that token, so look at it and at the words just before it. Sometimes the real mistake is earlier: in SELECT TOP 5 name FROM products SQLite reads TOP as a column name, so the error is at "5", and in SELECT * FROM products WHER id = 1 the misspelt WHER is taken as a table alias and the error is at "id". Recent sqlite3 shells (3.50.6 here) also print the statement with a caret line under the error position.
Most cases are SQL from another database. SQLite has no TOP (use LIMIT), no ALTER COLUMN or MODIFY (only RENAME TABLE, ADD COLUMN, RENAME COLUMN and DROP COLUMN), no SHOW TABLES, DESCRIBE, TRUNCATE, GRANT, DECLARE or ON DUPLICATE KEY UPDATE, and ISNULL is an SQLite operator (price ISNULL), so the SQL Server function ISNULL(price, 0) is a syntax error; use ifnull() or coalesce(). Some foreign syntax is accepted without doing what you expect: id INT AUTO_INCREMENT PRIMARY KEY and id INT IDENTITY(1,1) PRIMARY KEY both parse on 3.39.2 because the extra words become part of the type name, but neither assigns numbers (the IDENTITY column stayed NULL); use INTEGER PRIMARY KEY.
Features also depend on the SQLite version your program really uses, which is often older than the shell on your machine: UPSERT needs 3.24.0, window functions 3.25.0, UPDATE ... FROM 3.33.0, RETURNING and DROP COLUMN 3.35.0, RIGHT and FULL OUTER JOIN 3.39.0, and underscores in numbers (1_000) 3.46.0. A text that is cut off gives different messages: incomplete input when the statement ends without a semicolon (as PDO reported for SELECT * FROM products WHERE), and unrecognized token: "'Pen;" for a string that is never closed.
Common causes
- SQL Server or MySQL syntax that SQLite does not have: TOP, AUTO_INCREMENT after PRIMARY KEY, ALTER COLUMN or MODIFY, ISNULL(a, b), SHOW, DESCRIBE, TRUNCATE, ON DUPLICATE KEY UPDATE.
- A reserved word used as a table or column name without quotes: order, group, values, to, index and others.
- A missing or extra comma: a trailing comma before ")" in CREATE TABLE or before FROM, or a missing comma between two columns.
- A string containing an apostrophe that is not doubled, or a statement built by joining strings in code.
- A feature newer than the SQLite library your program uses (check sqlite_version() from the program), or one that needs a compile option, such as LIMIT on UPDATE and DELETE.
Diagnose it
Read-only These statements only read the schema (sqlite_schema and read-only PRAGMA queries) or your own data. They do not change data, settings or the database file, so they are safe to run first.
Which SQLite version does the program use?
Run this through the same driver as the failing statement. Python, PHP and Android usually bring their own SQLite library, which can be years older than the sqlite3 shell.
SELECT sqlite_version(); The library version, for example 3.39.2 for the PHP build used here. Compare it with the version that introduced the feature (RETURNING 3.35.0, RIGHT and FULL JOIN 3.39.0).
Is an optional syntax compiled in?
SELECT sqlite_compileoption_used('ENABLE_UPDATE_DELETE_LIMIT') AS update_delete_limit; 1 when UPDATE and DELETE accept ORDER BY and LIMIT, 0 otherwise. It returned 0 on PHP's 3.39.2, where UPDATE ... LIMIT 1 fails with near "LIMIT": syntax error. PRAGMA compile_options lists every option.
Does a function exist under that name?
When the token is a function name from another database, check what SQLite offers instead.
SELECT name
FROM pragma_function_list
WHERE name IN ('ifnull', 'coalesce', 'isnull', 'concat')
ORDER BY name; On 3.39.2: coalesce and ifnull. isnull is not a function (it is an operator keyword), and concat only exists from 3.44.0; use the || operator on older versions. A missing function normally gives "no such function"; ISNULL gives a syntax error because it is a keyword.
Read how an existing table was written
SELECT name, sql
FROM sqlite_schema
WHERE type = 'table'
ORDER BY name; The CREATE statements SQLite accepted, a reliable model for the syntax and quoting of new statements. Older versions name this table sqlite_master, and every version still accepts that name.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Use LIMIT instead of TOP (and OFFSET instead of FETCH)
Client or network sideSQLite puts the row limit at the end of the SELECT. OFFSET ... ROWS FETCH NEXT ... ROWS ONLY is also a syntax error on 3.39.2.
SELECT name
FROM products
ORDER BY price DESC
LIMIT 5; -- LIMIT 5 OFFSET 10 for the next page
Quote reserved words, or rename the object
Client or network sidePut a reserved word used as a name in double quotes every time you use it (SQLite also accepts [brackets] and `backticks` for compatibility). Renaming to a non-reserved name such as orders avoids the problem for good.
CREATE TABLE "order" (id INTEGER PRIMARY KEY, total REAL);
SELECT id, total FROM "order";
Write auto-numbered keys the SQLite way
Client or network sideA column declared exactly INTEGER PRIMARY KEY is filled automatically. Add AUTOINCREMENT (one word, after PRIMARY KEY) only if ids must never be reused after deletes.
CREATE TABLE products (
id INTEGER PRIMARY KEY, -- not INT AUTO_INCREMENT or IDENTITY(1,1)
name TEXT NOT NULL,
price REAL
);
Change a column type by rebuilding the table
Changes schemaSQLite has no ALTER COLUMN. To change a type or constraint, create a new table, copy the rows, drop the old table and rename the new one, inside a transaction (the full procedure, including indexes, triggers and views, is in the ALTER TABLE documentation).
Caution: Take a copy of the database first. DROP TABLE removes the old table's indexes and triggers, so recreate them; with foreign keys enabled, follow the documented steps (PRAGMA foreign_keys = OFF before the transaction, PRAGMA foreign_key_check before COMMIT).
BEGIN;
CREATE TABLE products_new (id INTEGER PRIMARY KEY, name TEXT NOT NULL, price NUMERIC);
INSERT INTO products_new (id, name, price) SELECT id, name, price FROM products;
DROP TABLE products;
ALTER TABLE products_new RENAME TO products;
COMMIT;
Pass values as parameters
Client or network sideBind values instead of pasting them into the SQL text. An apostrophe in a name then cannot break the statement, and the same code is safe from SQL injection. If you must write a literal, double the apostrophe: 'O''Brien'.
$stmt = $db->prepare('INSERT INTO customers (name) VALUES (?)');
$stmt->execute(["O'Brien"]);
Examples
A reserved word as a table name
CREATE TABLE order (
id INTEGER PRIMARY KEY,
total REAL
);
near "order": syntax error
Reproduced on SQLite 3.39.2, 24 October 2026.
SQL Server TOP instead of LIMIT
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price REAL);
SELECT TOP 5 name FROM products ORDER BY price DESC;
near "5": syntax error
Reproduced on SQLite 3.39.2, 24 October 2026.
MySQL AUTO_INCREMENT after PRIMARY KEY
CREATE TABLE products (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
name TEXT
);
near "AUTO_INCREMENT": syntax error
Reproduced on SQLite 3.39.2, 24 October 2026.
ALTER COLUMN, which SQLite does not support
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price REAL);
ALTER TABLE products ALTER COLUMN price TYPE NUMERIC;
near "ALTER": syntax error
Reproduced on SQLite 3.39.2, 24 October 2026.
How to prevent it
Write and test SQL against the SQLite version your application ships with (run SELECT sqlite_version() from the application), not only in a newer shell. When porting from SQL Server or MySQL, look for TOP, AUTO_INCREMENT, IDENTITY, ALTER COLUMN, ISNULL(), CONCAT() and ON DUPLICATE KEY UPDATE first.
Avoid reserved words as table and column names (orders rather than order), always use parameters for values, and use a SQL formatter or a recent sqlite3 shell (which shows a caret under the error position) to find where a long statement goes wrong.
Common questions
How do I fix "near ... : syntax error" in SQLite?
Look at the quoted token and the words just before it. Usual fixes: quote or rename a reserved word, remove a trailing comma, replace SQL Server or MySQL syntax (TOP, AUTO_INCREMENT, ALTER COLUMN, ISNULL) with the SQLite form, and check that your SQLite version supports the feature.
Why does SQLite point at the wrong word?
The parser reports the first token that cannot fit, and SQLite accepts many words as names. In SELECT TOP 5, TOP becomes a column name, so the error is at "5"; a misspelt WHER becomes a table alias, so the error is at the next word.
Does SQLite support RIGHT JOIN, FULL JOIN and RETURNING?
Yes in current versions: RIGHT and FULL OUTER JOIN from 3.39.0 and RETURNING from 3.35.0. Older libraries, often bundled with a language runtime or operating system, reject them, so check sqlite_version() from your program.
What is the difference between "syntax error" and "incomplete input"?
Both mean the statement cannot be parsed. "incomplete input" means the text ended before the statement was complete (and without a semicolon), for example a WHERE with nothing after it; with a semicolon the same text gives near ";": syntax error.
Learn more on CodeWithSQL
Official documentation
- SQLite keywords (and how to quote them)
- SQL features that SQLite does not implement
- ALTER TABLE (including the table rebuild procedure)
- Release history (when each feature was added)
Last technically reviewed 24 October 2026; examples and diagnostics run on SQLite 3.39.2 (PHP PDO_SQLITE) and the sqlite3 shell 3.50.6. Messages are the text the SQLite library itself returns (sqlite3_errmsg) for the versions shown.