PostgreSQL raises ERROR: invalid escape octet with SQLSTATE 2200D and condition name invalid_escape_octet when an escape sequence in a string or bytea literal contains a byte value that is not a valid octet — that is, outside the range 0–255. This is a data exception in error class 22.
What This Error Means
SQLSTATE 2200D belongs to error class 22 (Data Exception), a broad category covering violations of data format or value constraints. The specific condition invalid_escape_octet signals that PostgreSQL encountered an escape sequence representing a byte value that cannot be expressed as a single octet (0x00–0xFF).
In practice this error surfaces most often when working with bytea data using the traditional escape format. In bytea escape syntax, octal escapes take the form \nnn where nnn must be a three-digit octal value between \000 and \377 (0–255 decimal). If the octal digits represent a value greater than 255 — for example \400 or beyond — PostgreSQL rejects it as an invalid escape octet.
When this error occurs, the current statement is aborted. If you are inside a transaction block, the transaction is placed in an error state and must be rolled back before any further commands can execute. No data is written or modified.
Common Causes
Out-of-range octal escape in a
byteaescape-format literal. The escape format forbyteauses\nnnoctal notation, where valid values are\000through\377. Using a value like\400(decimal 256) exceeds the single-byte range and triggers this error.Manually constructed escape strings with arithmetic errors. Application code that builds
byteaescape strings programmatically can accidentally produce out-of-range octal sequences when the source integer values are not clamped to 0–255 before formatting.Importing or migrating data from a source that uses a different escape convention. Data exported from another system may embed escape sequences that do not follow PostgreSQL's octal format, resulting in invalid octet values when re-inserted.
Incorrect use of
E''escape syntax with byte values. String literals prefixed withE(escape strings) that contain\nnnsequences are interpreted as octal character codes. A value outside the valid byte range will raise this error.
How to Fix invalid_escape_octet
Use hex-format
bytealiterals instead of escape format. The hex format (\xprefix) is unambiguous, less error-prone, and the default output format since PostgreSQL 9.0:-- Escape format (error-prone for high byte values): SELECT E'\\377'::bytea; -- Hex format (preferred): SELECT '\xFF'::bytea; SELECT decode('FF', 'hex');Clamp byte values to the valid range (0–255) before constructing escape sequences. If you must produce escape-format
byteain application code, ensure every byte value is masked or clamped before formatting:# Python example: ensure value fits in a byte before encoding value = some_integer & 0xFF # mask to valid octet range escaped = "\\%03o" % valueUse parameterized queries and pass binary data as bytes, not as escaped strings. Most PostgreSQL drivers accept
bytes/bytearray/Buffertypes directly and handle the encoding transparently:# psycopg2 example — pass bytes directly, no manual escaping needed cursor.execute("INSERT INTO files (data) VALUES (%s)", (binary_data,))// JDBC example PreparedStatement ps = conn.prepareStatement("INSERT INTO files (data) VALUES (?)"); ps.setBytes(1, byteArray); ps.executeUpdate();Validate escape sequences before sending them to PostgreSQL. If you are processing text that may contain
\nnnsequences, parse and validate each octal value before constructing the query.Use
encode/decodefunctions for safe conversion. The built-inencodeanddecodefunctions handlebytea↔ text conversion safely:-- Convert binary data to/from hex or base64 without raw escape sequences SELECT encode(data, 'hex') FROM files; SELECT decode('deadbeef', 'hex');
Additional Information
- Error class 22 (Data Exception) contains many related conditions. Sibling SQLSTATE codes include
22000(data_exception),2200F(zero_length_character_string),22001(string_data_right_truncation),22003(numeric_value_out_of_range), and22021(character_not_in_repertoire). - The hex
byteaoutput format (bytea_output = 'hex') has been the default since PostgreSQL 9.0. Code still relying on the older escape format (bytea_output = 'escape') is more likely to encounter this error. - Most modern PostgreSQL drivers (psycopg2, psycopg3, asyncpg, JDBC, node-postgres) handle
byteaencoding automatically when you pass native binary types, eliminating the need to manually construct escape sequences and avoiding this error entirely. - This error is relatively rare in well-typed application code. It most commonly appears during data migrations, bulk imports of legacy data, or when hand-crafting SQL strings in scripts.
Frequently Asked Questions
What is the difference between bytea escape format and hex format?
Escape format represents binary data as a mix of printable ASCII and backslash-prefixed octal sequences (\nnn). Hex format (default since PostgreSQL 9.0) represents binary data as \x followed by hexadecimal digits. Hex format is simpler, unambiguous, and not susceptible to invalid octet errors because each byte is always represented as exactly two hex digits (00–FF).
Why does this error only happen with certain byte values?
A single octet holds values from 0 to 255 (decimal), or \000 to \377 in octal. Any octal escape sequence whose value exceeds \377 cannot fit in one byte, which is what this error reports. Hex values beyond FF would similarly exceed one byte, but PostgreSQL's hex bytea format processes two hex digits at a time, making it structurally impossible to specify an out-of-range value.
Can I configure PostgreSQL to ignore or accept invalid escape octets?
No. The invalid_escape_octet error is enforced by SQL standards compliance (it is a data exception) and cannot be suppressed through configuration. The correct approach is to fix the data or the code generating the escape sequences.
My ORM raises this error but I am not writing any escape sequences. Why?
Some ORMs or query builders serialize binary or blob fields as escaped strings internally, especially older versions or those targeting multiple database backends. Check whether your ORM has a PostgreSQL-specific bytea type adapter, and ensure you are using it rather than a generic string or blob type.