PostgreSQL-Fehlerreferenz

Die Fehler, die PostgreSQL Ihnen in der Produktion wirklich um die Ohren wirft, je eine Seite: was die Meldung bedeutet, die typischen Ursachen, wie man ihn diagnostiziert und behebt — mit echten Befehlen, ohne Geschwafel.

Verbindungen & Authentifizierung

SQLSTATE 53300

too many clients

max_connections ist erschöpft. Wie Sie sehen, wer die Slots hält, und warum die eigentliche Lösung meist ein Connection-Pooler ist, nicht ein höheres Limit.

Verbindungen

connection refused

Die TCP-Verbindung erreichte PostgreSQL überhaupt nicht. Server aus, falscher Port, listen_addresses, Firewall oder Docker-Netzwerk — in dieser Reihenfolge.

SQLSTATE 28P01

password authentication failed

Manchmal ist das Passwort wirklich falsch. Die anderen Male: die Rolle hat kein Passwort, SCRAM/md5-Mismatch oder eine URI, die Prozent-Kodierung gebraucht hätte.

SQLSTATE 28000

no pg_hba.conf entry

Der Server ist erreichbar, aber keine pg_hba.conf-Regel trifft Ihre Kombination aus (Host, Datenbank, Benutzer, SSL). Der Fehler sagt Ihnen genau welche.

SQLSTATE 3D000

database does not exist

Oft ist die im Fehler genannte Datenbank Ihr eigener Benutzername — psqls Standard, wenn Sie keinen angeben. Oder Sie sind komplett auf dem falschen Port.

SQLSTATE 28000

role does not exist

Frische Installation, und PostgreSQL weiß nicht, wer "ubuntu" ist. Warum der OS-Benutzername auftaucht und wie man Rollen richtig bootstrappt.

SQLSTATE 08006

server closed the connection

Entweder ist der Serverprozess gestorben (das Log wird es sagen) oder eine Firewall/NAT hat stillschweigend eine Idle-Verbindung gekappt (das Log wird schweigen). Prüfen Sie zuerst das Log.

Nebenläufigkeit & Sperren

SQLSTATE 40P01

deadlock detected

Zwei Transaktionen halten jeweils einen Lock, den die andere benötigt. Warum das passiert, wie man die DETAIL-Zeilen liest und welche Gewohnheiten bei der Lock-Reihenfolge es verhindern.

SQLSTATE 40001

could not serialize access

Repeatable Read oder Serializable weigerte sich, so zu tun, als seien zwei widersprüchliche Transaktionen beide geschehen. Kein Bug — aber Ihr Code muss wiederholen.

SQLSTATE 25P02

current transaction is aborted

Nie das eigentliche Problem: eine frühere Anweisung in der Transaktion ist bereits fehlgeschlagen, und PostgreSQL verweigert alles, bis Sie ROLLBACK ausführen.

SQLSTATE 55P03

lock timeout

Die Anweisung gab das Warten auf einen Lock auf — weil jemand vernünftigerweise lock_timeout gesetzt hat. Finden Sie den Blockierer und behalten Sie das Fail-Fast-Muster.

SQLSTATE 40001

conflict with recovery

Nur auf Replikas: WAL-Replay musste Zeilenversionen entfernen, die Ihre Query noch verwendete. Die Lösung ist ein Kompromiss, den Sie bewusst wählen müssen.

Constraints & Datenintegrität

SQLSTATE 23505

duplicate key value

Ein Unique-Constraint hat seine Aufgabe erfüllt. Die interessante Frage ist, warum: ein Insert-Race, eine bei einem Import zurückgebliebene Sequenz oder ein wiederholender Client.

SQLSTATE 23502

not-null violation

Eine NOT-NULL-Spalte würde leer bleiben. Die heimtückische Variante: Ihr ORM sendet ein explizites NULL, das den DEFAULT der Spalte überschreibt.

SQLSTATE 23503

foreign key violation

Zwei Richtungen, ein Constraint: ein Kind, das auf ein fehlendes Elternteil zeigt, oder ein Elternteil, das gelöscht wird, während Kinder es noch referenzieren.

SQLSTATE 22P02

invalid input syntax

Ein Textwert konnte nicht als Zieltyp geparst werden. Meist ein Cast auf schmutzige Daten, ein leerer String, wo eine Zahl erwartet wurde, oder eine CSV-Kopfzeile.

SQLSTATE 22001

value too long

Daten überschritten ein varchar(n)-Limit und PostgreSQL weigert sich, stillschweigend abzuschneiden. Oft ist die eigentliche Lösung, das (n) selbst zu hinterfragen.

SQLSTATE 22012

division by zero

Ein Nenner traf null — meist eine leere Gruppe in einer Aggregation. Der einzeilige Fix, den man sich merken sollte: NULLIF(nenner, 0).

SQLSTATE 42P10

no constraint matching ON CONFLICT

ON CONFLICT braucht einen Unique-Index auf genau den Spalten (oder dem Ausdruck oder dem Partial-Prädikat), die Sie genannt haben. Ein normaler Index zählt nicht.

SQL, Typen & Schema

SQLSTATE 42501

permission denied

Ihrer Rolle fehlt ein Recht — oft weil die Tabellen von der Migrations-Rolle erstellt wurden und niemand der App-Rolle etwas darauf erteilt hat.

SQLSTATE 42P01

relation does not exist

Die Tabelle existiert — Sie schauen nur nicht dort, wo PostgreSQL schaut. search_path, gequotete Bezeichner und falsche Datenbank, in dieser Reihenfolge.

SQLSTATE 42703

column does not exist

Drei Fallen verursachen die meisten davon: camelCase-Spalten, die Anführungszeichen brauchen, doppelt gequotete "Strings" (das sind Bezeichner!) und Aliase in WHERE.

SQLSTATE 42601

syntax error at or near

Das ^ zeigt, wo der Parser aufgab — der Fehler liegt meist dort oder kurz davor. Reservierte Wörter und MySQL-Syntax stehen ganz oben.

SQLSTATE 42883

function does not exist

Lesen Sie es als: keine Funktion mit diesem Namen und diesen Argumenttypen. Die Funktion existiert meist — Ihre Argumente haben den falschen Typ.

SQLSTATE 42803

must appear in GROUP BY

Sie haben eine Spalte selektiert, die weder gruppiert noch aggregiert ist. Oft ist die eigentliche Absicht "die neueste Zeile pro Gruppe" — was DISTINCT ON will, nicht GROUP BY.

SQLSTATE 21000

more than one row returned

Eine skalare Subquery versprach höchstens eine Zeile und lieferte mehrere. Entweder meinten Sie IN — oder Ihre Daten haben Duplikate, die sie nicht haben sollten.

Ressourcen & Betrieb

SQLSTATE 57014

statement timeout

Eine Query hat statement_timeout überschritten. Finden Sie heraus, ob sie langsam war, an einem Lock blockiert war oder das Timeout irgendwo gesetzt war, wo Sie es vergessen hatten.

SQLSTATE 53200

out of shared memory

Trotz des beängstigenden Namens füllt sich fast immer die gemeinsame Lock-Tabelle — typischerweise eine Transaktion, die Tausende Partitionen anfasst.

SQLSTATE 53100

no space left on device

Die Platte ist voll — und auf PostgreSQL-Hosts ist der Übeltäter oft WAL, das von einem toten Replikations-Slot zurückgehalten wird. Regel eins: nie von Hand aus dem Datenverzeichnis löschen.

Betrieb

wraparound protection

Die Notbremse von MVCC: Transaktions-IDs fast erschöpft, weil das Freezing zurückfiel. Finden Sie, was das Vacuum blockierte, und lassen Sie es dann aufholen.

Den SQLSTATE eines Fehlers finden

Jeder PostgreSQL-Fehler trägt einen fünfstelligen SQLSTATE-Code, der stabiler ist als der Meldungstext (und den Ihr Treiber für die programmatische Behandlung bereitstellt). Führen Sie in psql \set VERBOSITY verbose aus, und der Code wird bei jedem Fehler ausgegeben; lesen Sie im Anwendungscode das SQLSTATE-Feld aus dem Fehlerobjekt Ihres Treibers. Die Seiten oben nennen den SQLSTATE, der zu jedem Fehler gehört.