SQLSTATE 22010 occurs when PostgreSQL receives an invalid indicator parameter value in a prepared statement or function call. Indicator parameters are used to signal NULL values in parameterized queries, and this error means the indicator value provided does not conform to SQL standards.
SQLSTATE 22010 belongs to the SQL standard class 22 (data exception) and corresponds to "invalid indicator parameter value". In SQL, indicator parameters are special parameters used alongside regular parameters to indicate whether a value is NULL. They are typically used in embedded SQL, ODBC, JDBC, and other database interfaces that need to distinguish between NULL values and actual data. When you bind parameters to a prepared statement or call a stored procedure, the driver or application can provide an indicator parameter for each data parameter. If the indicator value is outside the valid range (usually -1 for NULL, 0 for non-NULL, and positive values for string truncation), PostgreSQL raises this error. This is a data validation error that occurs at the protocol level, not a logical error in your SQL. It typically indicates a bug in the database driver, ORM, or application code that is constructing the parameter bindings incorrectly.
First, capture the exact SQL statement and parameter values that trigger the error. Enable query logging in PostgreSQL:
-- Temporarily enable detailed logging
ALTER SYSTEM SET log_statement = 'all';
SELECT pg_reload_conf();
-- Or for session only
SET log_statement = 'all';Check the PostgreSQL logs to see the exact prepared statement and parameter bindings. Look for indicator parameter values that are not -1, 0, or positive integers.
Outdated drivers often have bugs in parameter binding logic. Update to the latest stable version:
# For Node.js/PostgreSQL (node-postgres/pg)
npm update pg
# For Python (psycopg2/psycopg3)
pip install --upgrade psycopg-binary
# For Java (JDBC)
# Update your pom.xml or build.gradle to use latest PostgreSQL JDBC driverAfter updating, test if the error persists. Check the driver's changelog for fixes related to parameter binding or indicator parameters.
If you're manually binding parameters with indicator values, verify the logic:
# Python psycopg example - WRONG
cursor.execute("INSERT INTO users (name, age) VALUES (%s, %s)",
("John", 25, 0)) # Extra 0 might be misinterpreted as indicator
# CORRECT - let driver handle NULL indicators
cursor.execute("INSERT INTO users (name, age) VALUES (%s, %s)",
("John", 25))
# For explicit NULL with indicator
cursor.execute("INSERT INTO users (name, age) VALUES (%s, %s)",
("John", None)) # Driver converts None to proper indicatorEnsure you're not passing extra parameters that the driver might misinterpret as indicator values.
Create a minimal test case to isolate the issue:
-- Simple test query
PREPARE test_query (text, integer) AS
INSERT INTO test_table (name, value) VALUES ($1, $2);
-- Execute with various parameter combinations
EXECUTE test_query ('test', 123);
EXECUTE test_query (NULL, 456);
EXECUTE test_query ('another', NULL);If the simple prepared statements work, the issue is likely in your application's parameter binding logic rather than PostgreSQL itself.
PostgreSQL's wire protocol has evolved over time. Ensure your client and server versions are compatible:
-- Check server version
SELECT version();
-- Check protocol version (client may show in connection logs)# Force specific protocol version if supported by driver
# Example for libpq (C library) environment variable
export PG_PROTOCOL_VERSION=3Some drivers allow forcing older protocol versions for compatibility. Consult your driver's documentation for protocol version options.
If you cannot immediately fix the driver or code, consider workarounds:
-- Instead of parameterized query with NULL indicators:
-- PREPARE insert_user (text, integer) AS INSERT INTO users VALUES ($1, $2);
-- Use COALESCE or CASE to handle NULLs in SQL:
PREPARE insert_user (text, integer) AS
INSERT INTO users VALUES (
CASE WHEN $1 IS NULL THEN NULL ELSE $1 END,
CASE WHEN $2 IS NULL THEN NULL ELSE $2 END
);
-- Or use dynamic SQL generation in application code
-- Build query string based on which parameters are NULLThese workarounds avoid indicator parameters altogether by handling NULLs at the SQL level.
Indicator parameters are part of the SQL standard (ISO/IEC 9075) for handling NULL values in parameterized statements. PostgreSQL supports them through its wire protocol and various client interfaces. The valid indicator values are: -1 (SQL_NULL_DATA) indicates the parameter is NULL, 0 (SQL_NON_NULL_DATA) indicates a non-NULL value, and positive integers indicate string truncation (length of original string before truncation). Some older drivers or custom implementations might use different values, causing this error. When debugging, use tools like Wireshark with PostgreSQL dissection or driver-specific debugging flags to inspect the actual wire protocol messages.
ERROR: syntax error at end of input
Syntax error at end of input in PostgreSQL
Bind message supplies N parameters but prepared statement requires M
Bind message supplies N parameters but prepared statement requires M in PostgreSQL
Multidimensional arrays must have sub-arrays with matching dimensions
Multidimensional arrays must have sub-arrays with matching dimensions
ERROR: value too long for type character varying
Value too long for type character varying
insufficient columns in unique constraint for partition key
How to fix "insufficient columns in unique constraint for partition key" in PostgreSQL