Riferimento errori PostgreSQL
Gli errori che PostgreSQL ti lancia davvero in produzione, una pagina ciascuno: cosa significa il messaggio, le cause tipiche, come diagnosticarlo e come risolverlo — con comandi reali, senza giri di parole.
Connessioni e autenticazione
too many clients
max_connections è esaurito. Come vedere chi tiene gli slot e perché la vera soluzione di solito è un connection pooler, non un limite più alto.
Connessioniconnection refused
La connessione TCP non ha mai raggiunto PostgreSQL. Server spento, porta sbagliata, listen_addresses, firewall o networking Docker — in quest'ordine.
SQLSTATE 28P01password authentication failed
A volte la password è davvero sbagliata. Le altre volte: il ruolo non ha password, mismatch SCRAM/md5, o una URI che richiedeva il percent-encoding.
SQLSTATE 28000no pg_hba.conf entry
Il server è raggiungibile ma nessuna regola pg_hba.conf corrisponde alla tua combinazione (host, database, user, SSL). L'errore ti dice esattamente quale.
SQLSTATE 3D000database does not exist
Spesso il database indicato nell'errore è il tuo stesso username — il default di psql quando non ne specifichi uno. Oppure sei del tutto sulla porta sbagliata.
SQLSTATE 28000role does not exist
Installazione nuova, e PostgreSQL non sa chi sia "ubuntu". Perché compare lo username OS, e come fare il bootstrap dei ruoli come si deve.
SQLSTATE 08006server closed the connection
O il processo del server è morto (il log lo dirà) o un firewall/NAT ha silenziosamente tagliato una connessione idle (il log tacerà). Controlla prima il log.
Concorrenza e lock
deadlock detected
Due transazioni tengono ciascuna un lock che serve all'altra. Perché succede, come leggere le righe DETAIL e le abitudini di ordinamento dei lock che lo prevengono.
SQLSTATE 40001could not serialize access
Repeatable Read o Serializable si è rifiutato di far finta che due transazioni in conflitto siano avvenute entrambe. Non è un bug — ma il tuo codice deve riprovare.
SQLSTATE 25P02current transaction is aborted
Mai il vero problema: uno statement precedente nella transazione è già fallito, e PostgreSQL rifiuta tutto finché non fai ROLLBACK.
SQLSTATE 55P03lock timeout
Lo statement ha rinunciato ad aspettare un lock — perché qualcuno ha sensatamente impostato lock_timeout. Trova chi blocca, e mantieni il pattern fail-fast.
SQLSTATE 40001conflict with recovery
Solo sui replica: il replay del WAL doveva rimuovere versioni di riga che la tua query stava ancora usando. La soluzione è un compromesso che devi scegliere consapevolmente.
Vincoli e integrità dei dati
duplicate key value
Un vincolo di unicità ha fatto il suo lavoro. La domanda interessante è perché: una race sull'insert, una sequence lasciata indietro da un import o un client che riprova.
SQLSTATE 23502not-null violation
Una colonna NOT NULL sarebbe rimasta vuota. La variante subdola: il tuo ORM invia un NULL esplicito, che sovrascrive il DEFAULT della colonna.
SQLSTATE 23503foreign key violation
Due direzioni, un vincolo: un figlio che punta a un padre mancante, o un padre in cancellazione mentre dei figli lo referenziano ancora.
SQLSTATE 22P02invalid input syntax
Un valore testuale non è stato interpretabile come il tipo di destinazione. Di solito un cast su dati sporchi, una stringa vuota dove serviva un numero, o un header CSV.
SQLSTATE 22001value too long
I dati hanno superato un limite varchar(n) e PostgreSQL rifiuta di troncare silenziosamente. Spesso la vera soluzione è mettere in discussione l'(n) stesso.
SQLSTATE 22012division by zero
Un denominatore è arrivato a zero — di solito un gruppo vuoto in un'aggregazione. La soluzione da una riga da memorizzare: NULLIF(denominatore, 0).
SQLSTATE 42P10no constraint matching ON CONFLICT
ON CONFLICT ha bisogno di un indice unique esattamente sulle colonne (o espressione, o predicato parziale) che hai indicato. Un indice normale non conta.
SQL, tipi e schema
permission denied
Al tuo ruolo manca un privilegio — spesso perché le tabelle sono state create dal ruolo delle migrazioni e nessuno ha concesso nulla al ruolo applicativo su di esse.
SQLSTATE 42P01relation does not exist
La tabella esiste — semplicemente non stai guardando dove guarda PostgreSQL. search_path, identificatori quotati e database sbagliato, in quest'ordine.
SQLSTATE 42703column does not exist
Tre trappole causano la maggior parte di questi: colonne camelCase che vanno quotate, "stringhe" tra doppi apici (quelli sono identificatori!), e alias in WHERE.
SQLSTATE 42601syntax error at or near
Il caret punta dove il parser si è arreso — l'errore di solito è lì o appena prima. Parole riservate e sintassi MySQL sono in cima alla lista.
SQLSTATE 42883function does not exist
Leggilo come: nessuna funzione con quel nome e quei tipi di argomento. La funzione di solito esiste — sono i tuoi argomenti a essere del tipo sbagliato.
SQLSTATE 42803must appear in GROUP BY
Hai selezionato una colonna che non è né raggruppata né aggregata. Spesso l'intento reale è "la riga più recente per gruppo" — che vuole DISTINCT ON, non GROUP BY.
SQLSTATE 21000more than one row returned
Una subquery scalare prometteva al più una riga e ne ha consegnate diverse. O intendevi IN — oppure i tuoi dati hanno duplicati che non dovrebbero esserci.
Risorse e operazioni
statement timeout
Una query ha sforato statement_timeout. Scopri se era lenta, bloccata su un lock, o se il timeout era impostato da qualche parte che avevi dimenticato.
SQLSTATE 53200out of shared memory
Nonostante il nome spaventoso, è quasi sempre la tabella dei lock condivisa che si riempie — tipicamente una transazione che tocca migliaia di partizioni.
SQLSTATE 53100no space left on device
Il disco è pieno — e sugli host PostgreSQL il colpevole è spesso il WAL trattenuto da un replication slot morto. Regola uno: mai cancellare a mano dalla directory dei dati.
Operazioniwraparound protection
Il freno d'emergenza dell'MVCC: transaction ID quasi esauriti perché il freezing è rimasto indietro. Trova cosa ha bloccato il vacuum, poi lascialo recuperare.
Trovare il SQLSTATE di un errore
Ogni errore PostgreSQL porta con sé un codice SQLSTATE di cinque caratteri, più stabile del testo del messaggio (ed è ciò che il driver espone per la gestione programmatica). In psql, esegui \set VERBOSITY verbose e il codice viene stampato con ogni errore; nel codice applicativo, leggi il campo SQLSTATE dall'oggetto errore del tuo driver. Le pagine qui sopra indicano il SQLSTATE corrispondente a ciascun errore.
