Référence des erreurs PostgreSQL

Les erreurs que PostgreSQL vous envoie vraiment en production, une page chacune : ce que signifie le message, les causes typiques, comment la diagnostiquer et comment la corriger — avec de vraies commandes, sans détour.

Connexions et authentification

SQLSTATE 53300

too many clients

max_connections est épuisé. Comment voir qui détient les slots, et pourquoi la vraie solution est généralement un pooler de connexions, pas une limite plus grande.

Connexions

connection refused

La connexion TCP n'a jamais atteint PostgreSQL du tout. Serveur arrêté, mauvais port, listen_addresses, pare-feu ou réseau Docker — dans cet ordre.

SQLSTATE 28P01

password authentication failed

Parfois le mot de passe est vraiment erroné. Les autres fois : le rôle n'a pas de mot de passe, une incohérence SCRAM/md5, ou un URI qui avait besoin d'un percent-encoding.

SQLSTATE 28000

no pg_hba.conf entry

Le serveur est joignable mais aucune règle pg_hba.conf ne correspond à votre combinaison (hôte, base, utilisateur, SSL). L'erreur vous dit exactement laquelle.

SQLSTATE 3D000

database does not exist

Souvent la base nommée dans l'erreur est votre propre nom d'utilisateur — la valeur par défaut de psql quand vous n'en spécifiez pas. Ou vous êtes carrément sur le mauvais port.

SQLSTATE 28000

role does not exist

Installation neuve, et PostgreSQL ne sait pas qui est « ubuntu ». Pourquoi le nom d'utilisateur OS apparaît, et comment amorcer les rôles correctement.

SQLSTATE 08006

server closed the connection

Soit le processus serveur est mort (le journal le dira) soit un pare-feu/NAT a silencieusement coupé une connexion inactive (le journal sera muet). Vérifiez d'abord le journal.

Concurrence et verrous

SQLSTATE 40P01

deadlock detected

Deux transactions détiennent chacune un verrou dont l'autre a besoin. Pourquoi cela arrive, comment lire les lignes DETAIL, et les habitudes d'ordonnancement des verrous qui l'évitent.

SQLSTATE 40001

could not serialize access

Repeatable Read ou Serializable a refusé de faire comme si deux transactions en conflit s'étaient toutes deux produites. Pas un bug — mais votre code doit réessayer.

SQLSTATE 25P02

current transaction is aborted

Jamais le vrai problème : une instruction antérieure dans la transaction a déjà échoué, et PostgreSQL refuse tout jusqu'à ce que vous fassiez un ROLLBACK.

SQLSTATE 55P03

lock timeout

L'instruction a renoncé à attendre un verrou — parce que quelqu'un a judicieusement défini lock_timeout. Trouvez le bloqueur, et conservez le motif fail-fast.

SQLSTATE 40001

conflict with recovery

Uniquement sur les réplicas : le rejeu WAL devait supprimer des versions de ligne que votre requête utilisait encore. La solution est un compromis que vous devez choisir consciemment.

Contraintes et intégrité des données

SQLSTATE 23505

duplicate key value

Une contrainte d'unicité a fait son travail. La question intéressante est pourquoi : une course à l'insertion, une séquence laissée en arrière par un import, ou un client qui réessaie.

SQLSTATE 23502

not-null violation

Une colonne NOT NULL se retrouverait vide. La variante sournoise : votre ORM envoie un NULL explicite, qui écrase le DEFAULT de la colonne.

SQLSTATE 23503

foreign key violation

Deux directions, une contrainte : un enfant pointant vers un parent absent, ou un parent en cours de suppression alors que des enfants le référencent encore.

SQLSTATE 22P02

invalid input syntax

Une valeur texte n'a pas pu être analysée comme le type cible. Généralement un cast sur des données sales, une chaîne vide là où on attendait un nombre, ou un en-tête CSV.

SQLSTATE 22001

value too long

Des données ont dépassé une limite varchar(n) et PostgreSQL refuse de tronquer silencieusement. Souvent la vraie solution est de remettre en question le (n) lui-même.

SQLSTATE 22012

division by zero

Un dénominateur a atteint zéro — généralement un groupe vide dans une agrégation. La solution en une ligne à mémoriser : NULLIF(denominator, 0).

SQLSTATE 42P10

no constraint matching ON CONFLICT

ON CONFLICT a besoin d'un index unique sur exactement les colonnes (ou l'expression, ou le prédicat partiel) que vous avez nommées. Un index ordinaire ne compte pas.

SQL, types et schéma

SQLSTATE 42501

permission denied

Votre rôle n'a pas un privilège — souvent parce que les tables ont été créées par le rôle de migration et que personne n'a accordé quoi que ce soit dessus au rôle applicatif.

SQLSTATE 42P01

relation does not exist

La table existe — vous ne regardez simplement pas là où PostgreSQL regarde. search_path, identifiants entre guillemets et mauvaise base, dans cet ordre.

SQLSTATE 42703

column does not exist

Trois pièges causent la plupart de ces cas : des colonnes camelCase nécessitant des guillemets, des « chaînes » entre guillemets doubles (ce sont des identifiants !), et des alias dans WHERE.

SQLSTATE 42601

syntax error at or near

Le caret pointe là où le parseur a abandonné — l'erreur est généralement dessus ou juste avant. Les mots réservés et la syntaxe MySQL sont en tête de liste.

SQLSTATE 42883

function does not exist

Lisez-le ainsi : aucune fonction de ce nom avec ces types d'arguments. La fonction existe généralement — ce sont vos arguments qui sont du mauvais type.

SQLSTATE 42803

must appear in GROUP BY

Vous avez sélectionné une colonne qui n'est ni groupée ni agrégée. Souvent la vraie intention est « la dernière ligne par groupe » — ce qui veut DISTINCT ON, pas GROUP BY.

SQLSTATE 21000

more than one row returned

Une sous-requête scalaire promettait au plus une ligne et en a livré plusieurs. Soit vous vouliez IN — soit vos données ont des doublons qu'elles ne devraient pas avoir.

Ressources et exploitation

SQLSTATE 57014

statement timeout

Une requête a dépassé statement_timeout. Déterminez si elle était lente, bloquée sur un verrou, ou si le timeout était défini quelque part que vous aviez oublié.

SQLSTATE 53200

out of shared memory

Malgré son nom effrayant, c'est presque toujours la table de verrous partagée qui se remplit — typiquement une transaction touchant des milliers de partitions.

SQLSTATE 53100

no space left on device

Le disque est plein — et sur les hôtes PostgreSQL le coupable est souvent du WAL retenu par un slot de réplication mort. Règle numéro un : ne jamais supprimer à la main dans le répertoire de données.

Opérations

wraparound protection

Le frein d'urgence de MVCC : identifiants de transaction presque épuisés parce que le gel a pris du retard. Trouvez ce qui a bloqué vacuum, puis laissez-le rattraper.

Trouver le SQLSTATE d'une erreur

Chaque erreur PostgreSQL porte un code SQLSTATE de cinq caractères, plus stable que le texte du message (et c'est ce que votre driver expose pour la gestion programmatique). Dans psql, exécutez \set VERBOSITY verbose et le code est affiché avec chaque erreur ; dans le code applicatif, lisez le champ SQLSTATE de l'objet erreur de votre driver. Les pages ci-dessus indiquent le SQLSTATE correspondant à chaque erreur.