↑↓ select↵ open⌫ change scopeOpen full search

PG.CENTER connects PostgreSQL documentation, reference, and ecosystem knowledge. Maintained by Pigsty.

Wiki / SQLSTATE

26000 — invalid_sql_statement_name

26000 means that PostgreSQL was asked to use a named prepared statement that does not exist in the current backend session. It is a session-resource lookup failure, so first check session affinity and statement lifecycle before changing the SQL text.

English manual coverage begins with PostgreSQL 8.1. Source history and runtime observations have their own recorded version boundaries.

Reading PG 18·Select a recorded version

aliases
Unknown
class name
Invalid SQL Statement Name
condition name
invalid_sql_statement_name
lang
en
sqlstate
26000

Definition PG 18

26000 — invalid_sql_statement_name

At a glance {#at-a-glance}

26000 means that PostgreSQL was asked to use a named prepared statement that does not exist in the current backend session. It is a session-resource lookup failure, so first check session affinity and statement lifecycle before changing the SQL text.

Meaning {#meaning}

PREPARE registers a named statement in one PostgreSQL session. EXECUTE and DEALLOCATE resolve that name in the same session; a pool checkout can silently move the next command to another backend. The core prepare.c path reports the dynamic name with prepared statement "%s" does not exist. The fixed extended-query path in postgres.c separately reports unnamed prepared statement does not exist when the unnamed statement is absent.

Diagnosis {#diagnosis}

Read the driver exception's SQLSTATE and primary message, then log the backend PID or an equivalent connection identity around PREPARE and EXECUTE. On that same connection, pg_prepared_statements can show whether the named entry exists; querying it on a different pooled connection is not evidence about the failing session. Distinguish a deallocation, a connection replacement, and an unnamed statement path from a malformed PREPARE statement.

Response {#response}

If the operation is inside an explicit transaction, roll back the failed block before issuing more commands. Recreate the statement on the session that will execute it, and keep the statement definition and parameter types under the same application or pool checkout. A missing statement has not itself applied the intended operation, but the application should still use its normal request identity and side-effect checks before repeating a larger workflow.

Messages {#messages}

The fixed core templates include prepared statement "%s" does not exist from prepare.c and unnamed prepared statement does not exist from the extended-query path in postgres.c. The selected case reports source_file = prepare.c and source_function = FetchPreparedStatement; only the named template has a server-side name substitution. Do not parse either message as a stable error string; branch on SQLSTATE and structured diagnostics.

Representative case {#case}

The runner reads this sequence from verify/cases/26000/snippets.json (SHA-256 b9fdbb48371e0d9902cb9e055ececc4878c38422773a8a1571651d9952809032) and keeps every statement on one connection. The complete executable record is the public case export, with structured evidence.

PREPARE statement_name(integer) AS SELECT $1 + 1;
EXECUTE statement_name(1);
DEALLOCATE statement_name;
EXECUTE statement_name(1);

statement_name is a page-level placeholder. The runner substitutes a unique identifier, deallocates it, asserts 26000 and IDLE, then repeats the registry's same three statements—PREPARE, EXECUTE, and DEALLOCATE—to repair the session. The recovery sequence is therefore: PREPARE the named statement again, EXECUTE it on that same connection, and DEALLOCATE it when the checkout is finished; these are the existing prepare, execute, and deallocate registry statements, not a second SQL definition.

The selected runner case observed 26000 on PostgreSQL 18.6 and 10.21. It deallocated a named statement, observed the dynamic missing-name diagnostic with the connection IDLE, then recreated and executed the statement on that same session.

Versions {#versions}

The locked catalogue reports this condition from the early historical boundary through the current formal snapshots. The fixed 18.6 source has both named and unnamed prepared-statement paths; the runtime comparison covers one named path on 18.6 and 10.21. The message wording and source line can vary by release, while the SQLSTATE identity remains 26000 in the selected targets.

Related {#related}

34000 invalid cursor name and 25P02 failed transaction are useful when a pool/session boundary or surrounding transaction is involved.

Sources {#sources}

  • src.errcodes.18.6 (SHA-256 6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)
  • src.prepare.18.6 (SHA-256 e37fbd5f7618e5554561d9293d8c3af7cf3190c62c5c6bbceb3fe8b97be17956)
  • src.postgres.18.6 (SHA-256 9fb62275b1badf94d01ab351337b60410cd9b3ab1fe63fa9f23d6d2185a21061)
  • PREPARE documentation · local call scan src.calls.REL_18_6 (SHA-256 9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)

Compare versions

SQLSTATE evidence and recorded runtime versions

cases · prepared_statement_recovery
{
  "assertions": [
    "SQLSTATE is 26000",
    "The prepared statement name is in the diagnostic",
    "The same session can recreate and execute the statement after the error"
  ],
  "case_id": "prepared_statement_recovery",
  "cleanup": "Drop the case schema with an owner connection.",
  "has_snippet": true,
  "position": 0,
  "preconditions": [
    "A runner-owned disposable target is provisioned."
  ],
  "repair": "Recreate the prepared statement on the session that will execute it; prepared statements are session-local.",
  "trigger": "Prepare a named statement, deallocate it, then execute the missing name on the same session.",
  "versions": [
    "10",
    "18"
  ]
}
claims · identity
{
  "claim_id": "identity",
  "limits": "The definition does not identify which SQL statement resource is missing.",
  "method": "Read the fixed errcodes.txt row and macro mapping.",
  "position": 0,
  "runtime": [],
  "sources": [
    "src.errcodes.18.6"
  ],
  "statement": "26000 is the invalid_sql_statement_name condition in Class 26."
}
claims · server-path
{
  "claim_id": "server-path",
  "limits": "The name is dynamic; this source path is from REL_18_6.",
  "method": "Trace ERRCODE_UNDEFINED_PSTATEMENT and errmsg in prepare.c.",
  "position": 1,
  "runtime": [],
  "sources": [
    "src.prepare.18.6",
    "src.calls.REL_18_6"
  ],
  "statement": "FetchPreparedStatement emits the source template prepared statement \"%s\" does not exist when a named prepared statement is absent."
}
claims · unnamed-path
{
  "claim_id": "unnamed-path",
  "limits": "This is a protocol/extended-query path and is not the selected named-statement runtime case; the message has no server-side name substitution.",
  "method": "Trace ERRCODE_UNDEFINED_PSTATEMENT and errmsg in the fixed unnamed-statement protocol path.",
  "position": 2,
  "runtime": [],
  "sources": [
    "src.postgres.18.6",
    "src.calls.REL_18_6"
  ],
  "statement": "The fixed postgres.c extended-query path emits unnamed prepared statement does not exist with SQLSTATE 26000 when the unnamed prepared statement is absent."
}
claims · session-scope
{
  "claim_id": "session-scope",
  "limits": "Connection pools can change backend sessions; this is a client/pool condition, not a promise about a particular driver.",
  "method": "Use the fixed PREPARE/EXECUTE documentation and the runner case lifecycle.",
  "position": 3,
  "runtime": [],
  "sources": [
    "doc.prepare.18.6"
  ],
  "statement": "PREPARE creates a session-local named statement; DEALLOCATE removes it, so EXECUTE must run on the same backend where the statement was created."
}
claims · runtime
{
  "claim_id": "runtime",
  "limits": "This covers the selected mechanism only, not all source callers or all driver/pool behavior.",
  "method": "Read the selected runner summaries and raw outputs tied to the shared snippet registry.",
  "position": 4,
  "runtime": [],
  "sources": [
    "runtime.26000-batch34-latest-20260909.latest",
    "runtime.26000-batch34-pg10-20260909.pg10"
  ],
  "statement": "The selected 26000 case passed on PostgreSQL 18.6 and 10.21 with the structured SQLSTATE, transaction-state, and repair assertions recorded in the runtime entries."
}
messages · message.prepared-missing
{
  "limits": "The unnamed prepared-statement path has a separate source template.",
  "message_id": "message.prepared-missing",
  "path": "",
  "position": 0,
  "raw": {
    "id": "message.prepared-missing",
    "limits": "The unnamed prepared-statement path has a separate source template.",
    "primary_template": "prepared statement \"%s\" does not exist",
    "severity_source": "ERROR",
    "sources": [
      "src.prepare.18.6"
    ],
    "sqlstate": "26000"
  },
  "severity": "ERROR",
  "sources": [
    "src.prepare.18.6"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "prepared statement \" \" does not exist",
      "position": 0,
      "role": "",
      "template": "prepared statement \"%s\" does not exist"
    }
  ]
}
messages · message.unnamed-prepared-missing
{
  "limits": "This fixed protocol path has no server-side statement-name substitution.",
  "message_id": "message.unnamed-prepared-missing",
  "path": "",
  "position": 1,
  "raw": {
    "id": "message.unnamed-prepared-missing",
    "limits": "This fixed protocol path has no server-side statement-name substitution.",
    "primary_template": "unnamed prepared statement does not exist",
    "severity_source": "ERROR",
    "sources": [
      "src.postgres.18.6"
    ],
    "sqlstate": "26000"
  },
  "severity": "ERROR",
  "sources": [
    "src.postgres.18.6"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "unnamed prepared statement does not exist",
      "position": 0,
      "role": "",
      "template": "unnamed prepared statement does not exist"
    }
  ]
}
runtimes · runtime.26000-batch34-latest-20260909.latest · 18.6 (Homebrew) · passed
{
  "cases": [
    "prepared_statement_recovery"
  ],
  "limits": "",
  "position": 0,
  "raw": {
    "case_manifest": {
      "path": "verify/cases/26000/cases.json",
      "sha256": "8a93385404eaff2506cf2da0c35e4c079b0f2a5750445fd5f2bc42130b54a6ca"
    },
    "cases": [
      "prepared_statement_recovery"
    ],
    "id": "runtime.26000-batch34-latest-20260909.latest",
    "observed": {
      "connection_autocommit": true,
      "primary": "prepared statement \"prepared_recovery_a347d8\" does not exist",
      "repair": {
        "values": {
          "after_recreate": 2,
          "before_deallocate": 2
        }
      },
      "severity": "ERROR",
      "sqlstate": "26000",
      "statuses": {
        "after_missing": "IDLE",
        "after_recreate": "IDLE"
      }
    },
    "raw": "verify/results/26000-batch34-latest-20260909/latest/raw.jsonl",
    "raw_sha256": "abdac32a6667920c0106f2bbd141bf47bb2614a0477a4e6a4322de13242a44ef",
    "run_id": "26000-batch34-latest-20260909",
    "server_version": "18.6 (Homebrew)",
    "snippet_registry": {
      "path": "verify/cases/26000/snippets.json",
      "sha256": "b9fdbb48371e0d9902cb9e055ececc4878c38422773a8a1571651d9952809032"
    },
    "status": "passed",
    "summary": "verify/results/26000-batch34-latest-20260909/latest/summary.json",
    "summary_sha256": "e6392b850858519b83a78884e27ba0e18c3f024b262549c1a63bc45648bc3265",
    "target": "latest"
  },
  "run_id": "26000-batch34-latest-20260909",
  "runtime_id": "runtime.26000-batch34-latest-20260909.latest",
  "server_version": "18.6 (Homebrew)",
  "status": "passed",
  "target": "latest"
}
runtimes · runtime.26000-batch34-pg10-20260909.pg10 · 10.21 (Debian 10.21-1.pgdg90+1) · passed
{
  "cases": [
    "prepared_statement_recovery"
  ],
  "limits": "",
  "position": 1,
  "raw": {
    "case_manifest": {
      "path": "verify/cases/26000/cases.json",
      "sha256": "8a93385404eaff2506cf2da0c35e4c079b0f2a5750445fd5f2bc42130b54a6ca"
    },
    "cases": [
      "prepared_statement_recovery"
    ],
    "id": "runtime.26000-batch34-pg10-20260909.pg10",
    "observed": {
      "connection_autocommit": true,
      "primary": "prepared statement \"prepared_recovery_8e5c66\" does not exist",
      "repair": {
        "values": {
          "after_recreate": 2,
          "before_deallocate": 2
        }
      },
      "severity": "ERROR",
      "sqlstate": "26000",
      "statuses": {
        "after_missing": "IDLE",
        "after_recreate": "IDLE"
      }
    },
    "raw": "verify/results/26000-batch34-pg10-20260909/pg10/raw.jsonl",
    "raw_sha256": "7dd35033652b224890790b92dffbfb00dce8f51e4e479fbfcd1590473b508f83",
    "run_id": "26000-batch34-pg10-20260909",
    "server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
    "snippet_registry": {
      "path": "verify/cases/26000/snippets.json",
      "sha256": "b9fdbb48371e0d9902cb9e055ececc4878c38422773a8a1571651d9952809032"
    },
    "status": "passed",
    "summary": "verify/results/26000-batch34-pg10-20260909/pg10/summary.json",
    "summary_sha256": "ae189293998b2d4d288658165f9ee288a89baef4227910e5c9aaec09d3a42099",
    "target": "pg10"
  },
  "run_id": "26000-batch34-pg10-20260909",
  "runtime_id": "runtime.26000-batch34-pg10-20260909.pg10",
  "server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
  "status": "passed",
  "target": "pg10"
}
sources · src.errcodes.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/utils/errcodes.txt",
  "position": 0,
  "sha256": "6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba",
  "source_id": "src.errcodes.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt"
}
sources · src.calls.REL_18_6
{
  "commit": "",
  "docs_url": "",
  "kind": "local_artifact",
  "location": "",
  "path": "raw/calls/REL_18_6.jsonl",
  "position": 1,
  "sha256": "9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf",
  "source_id": "src.calls.REL_18_6",
  "tag": "",
  "url": ""
}
sources · src.prepare.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/commands/prepare.c",
  "position": 2,
  "sha256": "e37fbd5f7618e5554561d9293d8c3af7cf3190c62c5c6bbceb3fe8b97be17956",
  "source_id": "src.prepare.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/prepare.c#L451-L454"
}
sources · src.postgres.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/tcop/postgres.c",
  "position": 3,
  "sha256": "9fb62275b1badf94d01ab351337b60410cd9b3ab1fe63fa9f23d6d2185a21061",
  "source_id": "src.postgres.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/postgres.c#L1670-L1672"
}
sources · doc.prepare.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "https://www.postgresql.org/docs/18/sql-prepare.html",
  "kind": "upstream_source",
  "location": "",
  "path": "doc/src/sgml/ref/prepare.sgml",
  "position": 4,
  "sha256": "0980f4925bdc3df25eaf4ca302b0ec43822731023a646aacebd8b01f69b2be71",
  "source_id": "doc.prepare.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/doc/src/sgml/ref/prepare.sgml"
}

Source references

Full definition and evidence JSON

Definition sources

center · PostgreSQL 18 · english-manuals:4be0637eae94350c9aa59d1e1819e002e9d28460b3a6d3b9504e53d26c09959b

Text language: en · english-manuals:4be0637eae94350c9aa59d1e1819e002e9d28460b3a6d3b9504e53d26c09959b