PostgreSQL Feature Not Supported (SQLSTATE 0A000)

PostgreSQL raises ERROR: <description> is not supported with SQLSTATE 0A000 and condition name feature_not_supported when you attempt to use a SQL construct, DDL option, or operational feature that either does not exist in the PostgreSQL implementation of standard SQL or is intentionally unsupported in your current version or configuration. The exact message text describes the specific feature that was requested and not found.

What This Error Means

SQLSTATE class 0A is the "Feature Not Supported" class defined by the SQL standard. Unlike runtime data errors (class 22) or integrity violations (class 23), this class signals a static limitation of the server itself — the operation you requested cannot be performed because the server does not implement it, regardless of the data or state involved.

PostgreSQL maps the single condition feature_not_supported to this class. The server raises it from many different internal code paths whenever it encounters a syntactically valid but semantically unsupported construct — for example, using DEFERRABLE on a non-deferrable constraint type, attempting to create a cross-database foreign key, or calling an SQL/XML or SQL/JSON function that PostgreSQL has not yet implemented.

After this error is raised the current statement is rolled back, but the transaction itself remains open (unless you are in autocommit mode). You can catch the condition in PL/pgSQL with EXCEPTION WHEN feature_not_supported THEN ... and take a fallback path without aborting the whole transaction.

Common Causes

  1. Unsupported DDL options on constraints or indexes. For example, attempting to declare a FOREIGN KEY constraint as DEFERRABLE INITIALLY DEFERRED when the referenced table is a partitioned table, or using EXCLUDE constraints with operator classes that do not support them, raises 0A000.

  2. Cross-database references. PostgreSQL does not support foreign keys or direct SELECT queries that span multiple databases within the same cluster. Trying to write SELECT * FROM other_db.public.orders raises feature_not_supported because cross-database access is not implemented (use dblink or postgres_fdw instead).

  3. Unsupported table features on partitioned or inherited tables. Operations such as adding a column WITH DEFAULT to a partitioned table, or creating a RULE on an inherited table, can trigger this error in older PostgreSQL versions where those combinations were not yet supported.

  4. SQL/XML or SQL/JSON functions not yet implemented. PostgreSQL implements much of the SQL standard incrementally. Functions like XMLQUERY returning non-scalar types, or certain JSON path expressions introduced in later revisions of the standard, may raise 0A000 in versions where that specific form is not yet available.

  5. Logical replication or WAL features that require specific configuration. Attempting to use pg_logical_slot_get_changes() or logical replication slots when wal_level is not set to logical results in a feature_not_supported error with a message such as ERROR: logical replication not enabled.

  6. Streaming replication commands issued on a non-standby. Sending a replication protocol command (e.g., START_REPLICATION) on a primary connection that was not opened with replication=true raises this error.

How to Fix feature_not_supported

  1. Read the full error message. The message text always names the specific feature. For example:

    ERROR:  cross-database references are not implemented: "otherdb.public.orders"
    SQLSTATE: 0A000
    

    or:

    ERROR:  logical replication not enabled
    HINT:  Enable logical replication by setting wal_level = 'logical'.
    SQLSTATE: 0A000
    

    The HINT line, when present, tells you exactly what to change.

  2. Use the recommended alternative for cross-database access. Install postgres_fdw and create a foreign server pointing to the other database:

    CREATE EXTENSION postgres_fdw;
    
    CREATE SERVER other_db_server
      FOREIGN DATA WRAPPER postgres_fdw
      OPTIONS (dbname 'other_db', host 'localhost');
    
    CREATE USER MAPPING FOR current_user
      SERVER other_db_server
      OPTIONS (user 'app_user', password 'secret');
    
    IMPORT FOREIGN SCHEMA public
      FROM SERVER other_db_server
      INTO foreign_schema;
    
    SELECT * FROM foreign_schema.orders;
    
  3. Enable the required server feature via postgresql.conf. For logical replication:

    # postgresql.conf
    wal_level = logical
    

    Then restart PostgreSQL and retry.

  4. Upgrade PostgreSQL. If the error message references a feature you know exists in a later version, upgrading resolves it. Check the PostgreSQL release notes for the version that introduced the feature.

  5. Restructure the DDL to avoid the unsupported combination. If you need deferrable foreign-key behavior on a partitioned table (not supported before PostgreSQL 16), refactor as a trigger-based constraint or restructure the partitioning strategy:

    -- Instead of DEFERRABLE FK on partitioned table (unsupported pre-PG16):
    -- Use an AFTER trigger to emulate deferred checking
    CREATE CONSTRAINT TRIGGER check_fk_deferred
      AFTER INSERT OR UPDATE ON orders
      DEFERRABLE INITIALLY DEFERRED
      FOR EACH ROW EXECUTE FUNCTION check_customer_exists();
    
  6. Open the connection in replication mode when using logical replication commands:

    psql "host=localhost dbname=mydb replication=database"
    

Additional Information

  • PostgreSQL 10 added support for logical replication slots; earlier versions will raise 0A000 for any attempt to use them.
  • PostgreSQL 16 lifted several restrictions on partitioned tables (deferrable foreign keys, MERGE on partitioned targets) that previously raised 0A000.
  • Drivers typically surface this as a PSQLException (JDBC), asyncpg.FeatureNotSupportedError, or PG::FeatureNotSupported (pg gem in Ruby). All expose the SQLSTATE 0A000.
  • Related SQLSTATE codes in adjacent classes: 42601 (syntax error — malformed SQL), 42809 (wrong object type), 42P17 (infinite recursion in rule).
  • This error is a statement-level error, not a transaction-terminating server crash. The session remains usable after catching it.

Frequently Asked Questions

Why do I get feature_not_supported even though the SQL looks standard? PostgreSQL implements the SQL standard incrementally. A construct may be valid SQL:2016 syntax while still being unimplemented in your PostgreSQL version. The error means PostgreSQL parsed the statement successfully but reached a code path that explicitly raises 0A000 because that particular behaviour is not yet built in.

Can I catch feature_not_supported in PL/pgSQL and fall back to alternative logic? Yes. Use the standard EXCEPTION block:

DO $$
BEGIN
  -- attempt the operation
  EXECUTE 'some statement that might raise 0A000';
EXCEPTION
  WHEN feature_not_supported THEN
    -- fallback path
    RAISE NOTICE 'Feature not available, using fallback';
END;
$$;

Why does my ORM raise this error when creating tables with certain column types or constraints? ORMs like Django or Rails generate DDL based on their own schema abstractions. If the generated DDL includes a feature combination that PostgreSQL does not support for your target version (e.g., an exclusion constraint on a partitioned table in PG 11), the migration will fail with 0A000. Review the generated SQL (--dry-run or EXPLAIN migrations) and adjust the model or migration to use a supported construct.

Is 0A000 always a configuration or version problem, or can it indicate a bug? It is almost always a version or configuration limitation, not a data problem or bug. The one exception is if a PostgreSQL extension raises 0A000 incorrectly — in that case the problem is in the extension, not in core PostgreSQL. Check the extension's changelog if you see this error from an extension function.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.