PostgreSQL raises ERROR: unterminated C string with SQLSTATE 22024 and condition name unterminated_c_string when a C-style (null-terminated) string passed to or returned by an internal PostgreSQL function is missing its terminating null byte. This error belongs to error class 22 (Data Exception).
What This Error Means
SQLSTATE class 22 covers data exceptions — errors that occur when the actual data values being processed violate expectations, rather than structural or permission problems. Within that class, 22024 specifically signals that PostgreSQL encountered a C string that does not end with the required null byte (\0).
PostgreSQL's internal C code, as well as C-language extension functions loaded via CREATE FUNCTION ... LANGUAGE C, work with null-terminated strings natively. When a string argument reaches an internal function that expects a C string, PostgreSQL verifies it can be safely treated as one. If the string data is malformed — for instance, because it was constructed by a buggy extension, passed through a low-level binary interface, or copied from corrupted storage — and the null terminator is absent, PostgreSQL raises 22024 rather than read beyond the allocated buffer.
After this error occurs the current transaction is aborted. Any subsequent statements in the same transaction will fail with ERROR: current transaction is aborted, commands ignored until end of transaction block until you issue a ROLLBACK (or ROLLBACK TO SAVEPOINT). The server process itself is unaffected; only the session's current transaction is rolled back.
Common Causes
Buggy C-language extension functions. A custom extension written in C that constructs or returns a
char *without appending\0will trigger this error when PostgreSQL's input/output infrastructure processes the string. This is the most common real-world cause.Corrupted data in
byteaor text columns passed to internal functions. Calling a function that internally converts abyteavalue to a C string (for example, certain regex or encoding functions) with data that lacks a null terminator can reproduce this error.Direct use of server-internal functions with crafted binary input. Functions exposed via
pg_catalogthat acceptcstringpseudo-type arguments (such as type input functions) expect a genuine null-terminated string. Passing raw bytes throughpsql\lo_*commands or vialibpqbinary protocol in a way that omits the null byte will raise22024.Extension or foreign data wrapper (FDW) bugs. An FDW or background worker that builds string arguments for PostgreSQL internal APIs without proper null termination can surface this error in production, often intermittently depending on heap layout.
How to Fix unterminated_c_string
If caused by a third-party or custom extension, update or patch it. The fix belongs in the C code that builds the string. Every
char *handed to a PostgreSQL internal function must end with\0. The canonical pattern in extension code is:/* Correct: allocate one extra byte and terminate */ char *buf = palloc(len + 1); memcpy(buf, src, len); buf[len] = '\0';If you cannot modify the extension, check whether a newer version fixes the bug and upgrade.
Reproduce with a minimal test case and isolate the bad input. If the error appears on specific rows, identify which value triggers it:
-- Test whether a specific column value causes the error SELECT your_function(col) FROM your_table WHERE id = <suspect_id>;Narrow down the problematic row, then decide whether to clean the data or skip the row.
Validate binary data before passing it to string-expecting functions. If you are working with
byteacolumns and converting them to text, ensure the byte sequence ends with\x00where required:-- Check if a bytea value ends with a null byte SELECT octet_length(your_bytea_col), right(your_bytea_col::text, 4) FROM your_table WHERE id = <suspect_id>;Wrap risky calls in a savepoint to limit transaction damage. When you expect possible
22024errors during batch processing, use savepoints so only the failing statement is rolled back:BEGIN; SAVEPOINT sp1; SELECT your_function(col) FROM your_table; -- If error occurs: ROLLBACK TO SAVEPOINT sp1; -- Continue processing other rows COMMIT;For
cstring-accepting internal functions, never bypass the text/varchar layer. Prefer passing values astextorvarcharand letting PostgreSQL's type system handle the conversion rather than callingcstring-typed functions directly.
Additional Information
- SQLSTATE
22024is defined in the SQL standard as well as in PostgreSQL. It has been present in PostgreSQL across all supported versions; there is no version-specific behavior change to note. - Related SQLSTATE codes in class
22include:22000(data exception),22001(string data right truncation),22003(numeric value out of range),22007(invalid datetime format),22P02(invalid text representation), and22021(character not in repertoire). - Client drivers such as
libpq,psycopg2,asyncpg, and JDBC all surface this as aDataException(or equivalent) withsqlstate = "22024". Check thepgcodeattribute in psycopg2 or thegetSQLState()method in JDBC to distinguish it from other data exceptions. - This error is rare in plain SQL workloads. It almost always points to a C-level bug in an extension, FDW, or background worker rather than to user data or SQL logic. If you see it without any custom extensions loaded, check for PostgreSQL bugs in your version and consider filing a bug report.
Frequently Asked Questions
Why does this error say "C string" — I'm not writing C code?
PostgreSQL's internal runtime is written in C, and many type input/output functions and extensions use C-style null-terminated strings internally. Even when you write plain SQL, the values you pass may be handled by C functions under the hood. SQLSTATE 22024 surfaces when one of those internal C functions receives data that does not conform to the null-termination contract expected by C strings.
Can corrupted PostgreSQL storage cause this error?
In theory, badly corrupted heap pages could cause a C string to lose its null terminator, but this is extremely unlikely in practice. The far more common cause is a buggy extension or FDW. If you suspect storage corruption, run VACUUM and check the PostgreSQL logs for other signs of corruption such as checksum failures or invalid page messages.
My query worked fine for months and now raises 22024 — what changed? The most likely culprit is an extension or FDW upgrade (or downgrade) that introduced a bug in string handling, or new data that exercises a previously untested code path in an existing extension. Check whether any extensions were updated around the time the error started appearing, and review the extension's changelog for C-string-related fixes.
Is this a security vulnerability? In PostgreSQL itself the error is a safe defensive check — the server raises the exception rather than reading past the buffer, so it does not lead to a buffer overread in the server process. However, the root cause (a missing null terminator in extension code) could be a sign of a broader memory-safety issue in that extension. Audit the extension's C code if you own it.