SQLSTATE 22022 occurs when an indicator variable or parameter is not large enough to hold the value being returned from a query or stored procedure. This typically happens in embedded SQL or driver-level parameter handling where indicator parameters are used to signal NULL values or data length information.
SQLSTATE 22022 belongs to the SQL standard class 22 (data exception) and corresponds to "indicator overflow". In SQL, indicator parameters are special variables used in embedded SQL and database interfaces (ODBC, JDBC, etc.) to: 1. Signal whether a value is NULL (using values like -1 for NULL, 0 for non-NULL) 2. Report the actual length of string data when it exceeds the buffer size 3. Handle truncation information during data transfer When "indicator overflow" occurs, it means the indicator parameter itself—the variable meant to hold metadata about the data—doesn't have enough storage capacity. For example, if an indicator is defined as a small integer (1 byte) but needs to store a larger value (like the actual length of a truncated string result), the overflow happens. This is a protocol-level data validation error, not a SQL logic error. It indicates a mismatch between how your application declared indicator variables and how PostgreSQL is trying to use them.
Enable detailed query logging in PostgreSQL to capture the exact statement causing the overflow:
-- Enable statement logging temporarily
ALTER SYSTEM SET log_statement = 'all';
ALTER SYSTEM SET log_min_error_statement = 'DEBUG3';
SELECT pg_reload_conf();
-- Or for current session only
SET log_statement = 'all';
SET log_min_error_statement = 'DEBUG3';Check the PostgreSQL server logs to find the exact query and examine what data sizes it returns. Look for any NULL values or large character/binary data that might trigger the overflow.
If you're using embedded SQL or have direct control over indicator variables, increase their size to accommodate larger values:
/* C embedded SQL - WRONG */
short indicator; /* Only stores -1 to 32767 */
char name[50];
EXEC SQL SELECT name INTO :name:indicator FROM users WHERE id = 1;
/* CORRECT */
int indicator; /* Stores much larger values */
char name[50];
EXEC SQL SELECT name INTO :name:indicator FROM users WHERE id = 1;Use a sufficiently large integer type for indicators. In most cases, an int (32-bit) or long (64-bit) is safer than short.
Outdated database drivers often have bugs in indicator parameter handling. Update to the latest stable version:
# For ODBC (Linux)
# Update your ODBC driver package
sudo apt-get install odbc-postgresql # Ubuntu/Debian
# or
sudo yum install postgresql-odbc # RHEL/CentOS
# For JDBC, update in your pom.xml or build.gradle
# <dependency>
# <groupId>org.postgresql</groupId>
# <artifactId>postgresql</artifactId>
# <version>42.7.0</version> <!-- Use latest -->
# </dependency>
# For Python (psycopg)
pip install --upgrade psycopg[binary]Check the driver's release notes for fixes related to "indicator overflow" or "parameter binding".
Ensure your application allocates enough memory for the result columns:
-- First, check the actual column sizes in your table
SELECT
column_name,
data_type,
character_maximum_length
FROM information_schema.columns
WHERE table_name = 'your_table'
ORDER BY ordinal_position;/* Allocate buffers generously - no penalty for extra space */
#define NAME_BUFFER_SIZE 256 /* Larger than column maximum */
#define DESC_BUFFER_SIZE 1024
char name[NAME_BUFFER_SIZE];
char description[DESC_BUFFER_SIZE];
int indicator_name, indicator_desc;
/* Now safe to fetch */
EXEC SQL SELECT name, description
INTO :name:indicator_name, :description:indicator_desc
FROM products WHERE id = 123;Always allocate more buffer space than the maximum column size to prevent truncation.
Configure how your driver handles NULL indicators to avoid overflow:
// JDBC example - configure how NULLs are handled
Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
// Use getXxx methods with column index and check for NULL
ResultSet rs = stmt.executeQuery("SELECT name, age FROM users");
while (rs.next()) {
String name = rs.getString(1); // Driver handles indicator internally
if (rs.wasNull()) {
System.out.println("Name is NULL");
} else {
System.out.println("Name: " + name);
}
}Modern drivers handle NULL indicators internally—avoid manual indicator variable management when possible.
For parameterized queries, declare parameters with appropriate data types:
-- WRONG - unclear parameter types and sizes
PREPARE get_user AS SELECT * FROM users WHERE name = $1;
-- BETTER - explicit types
PREPARE get_user (text) AS SELECT * FROM users WHERE name = $1;
PREPARE get_user_batch (text[], integer) AS
SELECT * FROM users WHERE name = ANY($1) AND age > $2;For ODBC applications using SQLBindParameter, specify accurate column sizes:
/* Set appropriate cbColumnDef (column definition size) */
SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR,
50, /* cbColumnDef: actual column size */
0, name_value, strlen(name_value), NULL);Create minimal test cases to isolate the problem:
-- Test 1: Simple SELECT with no NULL handling
SELECT id, name FROM users LIMIT 1;
-- Test 2: SELECT with guaranteed NULL values
SELECT id, name FROM users WHERE name IS NULL LIMIT 1;
-- Test 3: SELECT with large text columns
SELECT id, description FROM products WHERE length(description) > 1000;Run each test through your ODBC/JDBC connection to pinpoint which query triggers the overflow. This narrows down whether the issue is:
- Specific to NULL handling
- Related to data size
- A general driver bug
Indicator parameters are part of the SQL standard (ISO/IEC 9075) for embedded SQL. The indicator mechanism pre-dates modern ORMs and was designed for older programming models. In a "22022: indicator_overflow" error, PostgreSQL or the driver is attempting to write a value into an indicator variable that is too small. The most common scenario occurs when retrieving CHARACTER VARYING data: the indicator should hold the actual string length, but if the indicator is declared as SMALLINT (2 bytes, max 32767), it overflows when the actual data is longer. Modern applications should prefer using higher-level driver APIs (JDBC ResultSet, psycopg fetchall, etc.) that handle indicators transparently rather than manual embedded SQL with exposed indicator variables. If you must use embedded SQL, always declare indicators as large integer types (at least 32-bit int). Some databases allow NULL indicators to be optional—consult your driver documentation to disable indicator handling altogether if not needed.
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