PostgreSQL raises ERROR: invalid escape sequence with SQLSTATE 22025 (invalid_escape_sequence) when a string literal or LIKE pattern contains a backslash escape sequence that PostgreSQL does not recognize. You will see a message similar to:
ERROR: invalid escape sequence: "\m"
LINE 1: SELECT * FROM logs WHERE message LIKE '%\match%';
HINT: If you meant to write a backslash, use "\\".
The condition name is invalid_escape_sequence and it belongs to error class 22 (Data Exception).
What This Error Means
Error class 22 covers data value problems — situations where the data itself, rather than the SQL syntax, is wrong. SQLSTATE 22025 specifically means PostgreSQL encountered a \ in a string or LIKE/SIMILAR TO pattern and the character that follows it does not form a valid escape sequence.
PostgreSQL recognizes a specific set of C-style escape sequences in escape string literals (strings prefixed with E): \n, \t, \r, \\, \b, \f, \v, \uXXXX, \UXXXXXXXX, \ooo (octal), and \xHH (hex). If the character after \ is not one of these, the engine cannot interpret the sequence and raises 22025.
The behavior depends heavily on the standard_conforming_strings setting. When standard_conforming_strings = on (the default since PostgreSQL 9.1), backslashes in ordinary string literals ('...') are treated as literal characters, not escape characters — so '\m' is just a two-character string. The error arises only inside escape string literals (E'...') or inside LIKE patterns where the escape character is active. When standard_conforming_strings = off (legacy mode still found in older setups or migrated databases), all string literals behave like escape strings, making this error much more common.
After this error is raised, the current transaction is aborted. Any subsequent statements in the same transaction block will fail with ERROR: current transaction is aborted, commands ignored until end of transaction block until you issue ROLLBACK.
Common Causes
Unintended backslash in an E-string literal. Using
E'...'syntax and including a\followed by a character that is not a recognized escape, such asE'\d',E'\m', orE'\p'.Backslash in a
LIKEpattern withstandard_conforming_strings = off. In legacy escape mode,'%file\name%'tries to interpret\nas a newline — if the character after\is unrecognized, PostgreSQL raises 22025 instead of silently ignoring it.Application code building SQL strings with regex patterns or file paths. Languages like Python, Java, or Ruby often use
\d,\w, etc. in regular expressions or\Users\...in Windows paths. When these strings are injected directly into SQL without escaping, the backslashes land inside a PostgreSQL string literal and trigger the error.Using
SIMILAR TOwith regex-style escape sequences.SIMILAR TOpatterns in PostgreSQL use\as the default escape for the special characters%and_, but sequences like\dare not valid and will raise 22025.Migration from MySQL. MySQL interprets
\n,\t, and many other sequences in all string literals by default. SQL migrated from MySQL may contain these sequences in ordinary string literals, which then fail under PostgreSQL's escape string rules.
How to Fix invalid_escape_sequence
Double the backslash to produce a literal backslash. Inside an
E'...'string, use\\wherever you want a single\:-- Wrong (in legacy mode or E-strings): SELECT * FROM files WHERE path LIKE 'C:\Users\%'; -- Correct: SELECT * FROM files WHERE path LIKE E'C:\\Users\\%';Switch to dollar-quoting for strings containing many backslashes. Dollar-quoted strings (
$$...$$) never interpret backslashes, making them ideal for file paths or regex patterns:SELECT * FROM files WHERE path LIKE $$C:\Users\%$$;Avoid
E'...'when you do not need escape sequences. Use ordinary single-quoted strings ('...') withstandard_conforming_strings = on(the default). In this mode,'C:\Users\'is a literal string with no escape processing, so backslashes are safe:-- Safe with standard_conforming_strings = on (default): SELECT * FROM files WHERE path LIKE 'C:\Users\%';Use parameterized queries in application code. The safest fix is to pass strings as bind parameters rather than interpolating them into SQL. The driver handles escaping automatically:
# Python with psycopg2 — backslashes in the value are passed safely cursor.execute( "SELECT * FROM files WHERE path LIKE %s", (r'C:\Users\%',) )Check and set
standard_conforming_stringsexplicitly. If you are migrating from a legacy codebase, verify the setting and update strings accordingly:SHOW standard_conforming_strings; -- If 'off', consider migrating strings and enabling it: SET standard_conforming_strings = on;For
LIKEpatterns, specify a different escape character or disable escaping. PostgreSQL'sLIKEclause supports a customESCAPEclause. Setting it to an empty string disables escape processing entirely if backslash handling is causing problems:SELECT * FROM logs WHERE message LIKE '%\d+%' ESCAPE '';
Additional Information
standard_conforming_stringsdefaulted tooffbefore PostgreSQL 9.1 and toonfrom 9.1 onward. If you are on a very old cluster or havestandard_conforming_strings = offinpostgresql.conf, backslash escaping applies to all string literals, making this error significantly more common.- Related SQLSTATE codes in class 22: 22019 (
invalid_escape_character) — raised when the character specified in aLIKE ... ESCAPE '...'clause is not exactly one character; 22021 (character_not_in_repertoire) — a character encoding issue; 2200C (invalid_use_of_escape_character) — raised in specific contexts where the escape character appears in an invalid position. - Client libraries such as
libpq,psycopg2,node-postgres, and JDBC all surface this as aPSQLExceptionor similar with the SQLSTATE22025. Some ORMs (e.g., SQLAlchemy) may wrap it in their own exception hierarchy, but the underlying SQLSTATE is preserved. - The
escape_string_warningGUC parameter (defaulton) causes PostgreSQL to emit aWARNINGwhen a backslash appears in a non-escape string literal understandard_conforming_strings = on. This warning is a useful early indicator that code is relying on legacy escape behavior before it breaks in stricter modes.
Frequently Asked Questions
Why does this error only happen in some environments but not others?
The most common reason is a difference in standard_conforming_strings between environments. A development database created recently will have standard_conforming_strings = on (safe), while an older production database or one restored from a legacy dump may have it off, causing backslashes to be interpreted as escapes everywhere.
I see this error in a LIKE pattern — how is \ an escape in LIKE?
PostgreSQL's LIKE operator uses \ as a default escape character regardless of the standard_conforming_strings setting. This lets you match literal % and _ characters (e.g., '100\%' matches the string 100%). If your pattern contains \ followed by any other character, PostgreSQL raises 22025 because that sequence is not valid for LIKE escaping. Use ESCAPE '' or ESCAPE '!' to change or disable the escape character.
My ORM is generating invalid queries with backslashes — how do I fix it?
Use parameterized/prepared statements rather than string interpolation to build queries. For raw SQL methods in ORMs (e.g., Django's RawSQL, SQLAlchemy's text()), pass values as bound parameters. If you must include a literal backslash in a SQL string constant, use $$...$$ dollar-quoting or double the backslash (\\).
Can I suppress this error and treat unrecognized escape sequences as literal characters?
No — 22025 is a hard error, not a warning, and cannot be suppressed in the query itself. The correct fix is to write valid escape sequences or avoid escape processing. If you want backslashes to always be literal, use ordinary string literals with standard_conforming_strings = on, which is already the default.