PostgreSQL bağlantı hatalarını çözmenin anahtarı, mesajın bağlantının hangi aşamasında oluştuğunu anlamaktır. Connection refused ya da could not connect, istemcinin o adres ve portta dinleyen bir sunucu bulamadığını gösterir: sunucu kapalıdır, başka portta çalışıyordur veya listen_addresses o arayüzü kapsamıyordur. no pg_hba.conf entry ve password authentication failed ise sunucuya ulaştığınızı ama kimlik doğrulamada reddedildiğinizi söyler. too many clients already ise bağlantı yuvalarının dolduğunu bildirir. İlk kontrol aracı pg_isready'dir.

Bu yazıdaki tüm mesajlar PostgreSQL 18.1 üzerinde, yalnızca 127.0.0.1 adresini dinleyen deneme kümelerinde gerçekten üretildi. Kılavuzun "Client Connection Problems" ve "Authentication Problems" bölümleri, pg_isready sayfası ve bağlantı parametreleri temel alındı. Sorgu çalışırken alınan hatalar için sık hatalar ve SQLSTATE kodları, serinin tamamı için PostgreSQL öğrenme rehberi yazısına bakın.

Bağlantı aşamaları ve hata haritası

Bağlantı aşamaları ve hata haritası: Connection refused, Connection timed out, No such file or directory (soket), no pg_hba.conf entry for host

Bir istemci bağlanırken sırayla şu adımlar gerçekleşir: adresin çözülmesi ve TCP bağlantısı, sunucunun pg_hba.conf içinde bağlantıya uyan ilk satırı bulması, o satırdaki yöntemle kimlik doğrulama, rolün ve veritabanının varlık kontrolü, son olarak boş bir bağlantı yuvasının ayrılması. Her aşamanın kendine özgü mesajı vardır:

MesajAşamaİlk bakılacak yer
Connection refusedTCP: orada dinleyen sunucu yokSunucu çalışıyor mu, port, listen_addresses
Connection timed outAğAğ bağlantısı, güvenlik duvarı
No such file or directory (soket)Unix soketi bulunamadıSunucu çalışıyor mu, unix_socket_directories
no pg_hba.conf entry for hostErişim kuralı eşleşmedipg_hba.conf satırları
password authentication failedKimlik doğrulamaParola, rolün parolası, yöntem
role ... does not existRol kontrolüKullanıcı adı
database ... does not existVeritabanı kontrolüVeritabanı adı
remaining connection slots are reserved / too many clients alreadyYuva ayrılmasımax_connections ve açık bağlantılar

Önce: sunucu çalışıyor mu? pg_isready

pg_isready bir sunucunun bağlantı durumunu denetler ve sonucu çıkış koduyla bildirir: 0 bağlantı kabul ediliyor, 1 sunucu bağlantıları reddediyor (örneğin başlangıç sırasında), 2 bağlantı denemesine yanıt yok, 3 deneme yapılmadı (örneğin geçersiz parametre). Varsayılan zaman aşımı 3 saniyedir ve -t ile değişir. Betiklerde -q ile mesajı susturabilirsiniz. Çalışan ve çalışmayan iki port üzerinde:

bash
pg_isready -h 127.0.0.1 -p 46481; echo $?
pg_isready -h 127.0.0.1 -p 46489; echo $?
text
127.0.0.1:46481 - accepting connections
0
127.0.0.1:46489 - no response
2

Kılavuzun bir notu önemlidir: durum öğrenmek için doğru kullanıcı adı, parola veya veritabanı vermek gerekmez, ama yanlış değer verirseniz sunucu başarısız bir bağlantı denemesi kaydeder. Bunu kendi logumuzda gördük: -U vermeden çalıştırılan bir pg_isready, işletim sistemi kullanıcı adını kullandı ve logda FATAL: role "egeme" does not exist satırı oluştu. İzleme betiklerinde -U ile var olan bir rol adı verin ki log kirlenmesin.

Sunucunun kendi makinesindeyseniz pg_ctl status veri dizinindeki süreci kontrol eder. Durdurulmuş kümemizde çıktı şuydu ve çıkış kodu 3 oldu:

bash
pg_ctl -D /veri/dizini status
text
pg_ctl: no server running

Sunucuyu başlatma, durdurma ve log dosyası seçenekleri kurulum, initdb ve pg_ctl yazısında. Linux'ta servis olarak çalışan bir sunucunun durumu için systemd servis yönetimi yazısına bakabilirsiniz.

Connection refused

Connection refused: Port, listen_addresses, Güvenlik duvarı ve ağ, Doğru makine

Kılavuz bunu "konuşacak bir sunucu bulamadım" türünden genel hata olarak tanımlar. Dinlemeyen bir porta bağlandığımızda Windows üzerinde psql şunu yazdı:

bash
psql -h 127.0.0.1 -p 46489 -U postgres -d postgres
text
psql: error: connection to server at "127.0.0.1", port 46489 failed: Connection refused (0x0000274D/10061)
	Is the server running on that host and accepting TCP/IP connections?

Parantez içindeki 0x0000274D/10061 Windows'un hata kodudur; kılavuzdaki Linux örneğinde bu kısım yoktur. Kılavuzun altını çizdiği nokta şudur: bu bağlamda Connection refused, sunucunun isteğinizi alıp reddettiği anlamına gelmez; o adreste dinleyen bir süreç yoktur. Sunucu isteği alıp reddetseydi mesaj FATAL ile başlayan bir kimlik doğrulama hatası olurdu. Hata mesajı her zaman denenen adresi ve portu gösterir, bu yüzden önce istemcinin doğru yere gittiğini kontrol edin.

localhost yazıldığında istemci adı çözer ve her adresi sırayla dener. Sunucumuz yalnızca IPv4 dinlerken kapalı bir porta localhost ile bağlanınca iki deneme de ayrı ayrı raporlandı:

text
psql: error: connection to server at "localhost" (::1), port 46489 failed: Connection refused (0x0000274D/10061)
	Is the server running on that host and accepting TCP/IP connections?
connection to server at "localhost" (127.0.0.1), port 46489 failed: Connection refused (0x0000274D/10061)
	Is the server running on that host and accepting TCP/IP connections?

Sunucu çalışıyor ama yine de bu hatayı alıyorsanız kontrol listesi şöyledir:

  • Port: SHOW port; ile sunucunun portunu öğrenin. Kılavuza göre varsayılan 5432'dir, tüm IP adresleri için aynı port kullanılır ve parametre yalnızca sunucu başlarken ayarlanır.
  • listen_addresses: kılavuzun en sık hata olarak andığı nedendir. Varsayılan localhost'tur ve yalnızca yerel loopback bağlantılarına izin verir; uzak makineden bağlanmak için sunucunun dinlediği arayüzleri bu parametreye eklemeniz ve sunucuyu yeniden başlatmanız gerekir. * tüm arayüzler, 0.0.0.0 tüm IPv4, :: tüm IPv6 adresleri demektir. Deneme kümemizde SHOW listen_addresses; sonucu 127.0.0.1 idi.
  • Güvenlik duvarı ve ağ: kılavuza göre Connection timed out gibi mesajlar ağ bağlantısı eksikliğini ya da bağlantıyı engelleyen bir güvenlik duvarını gösterebilir.
  • Doğru makine: mesajdaki adres beklediğiniz sunucu mu? Ortam değişkenleri (PGHOST, PGPORT) ya da bağlantı dizesi sizi başka yere yönlendiriyor olabilir.
ini
# postgresql.conf (yalnızca sunucu başlarken okunur)
listen_addresses = 'localhost,10.0.0.5'
port = 5432

Unix benzeri sistemlerde -h verilmezse istemci Unix soketi üzerinden bağlanmaya çalışır. Kılavuzdaki örneğe göre bu durumda mesaj connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory biçimindedir (bu satır bir Linux mesajıdır, Windows test ortamımızda üretilmedi). Sunucu gerçekten çalışıyorsa istemcinin soket dizini ile sunucunun unix_socket_directories ayarının uyuştuğunu kontrol edin.

no pg_hba.conf entry for host

Bu mesaj sunucuya ulaştığınızı ama sunucunun bağlantıya uyan bir kural bulamadığını söyler. Deneme kümesinde pg_hba.conf dosyasına uygulama rolü için yalnızca ornek_upg veritabanına izin veren bir satır yazıp yapılandırmayı SELECT pg_reload_conf(); ile yeniden yükledik:

ini
# pg_hba.conf
host    ornek_upg  uygulama   127.0.0.1/32   scram-sha-256

Aynı rolle postgres veritabanına bağlanmayı denediğimizde:

text
psql: error: connection to server at "127.0.0.1", port 46481 failed: FATAL:  no pg_hba.conf entry for host "127.0.0.1", user "uygulama", database "postgres", no encryption

Mesaj dört bilgiyi birden verir: istemci adresi, kullanıcı, veritabanı ve şifreleme durumu. Sonundaki no encryption, bağlantının SSL olmadan yapıldığını gösterir; dosyada yalnızca hostssl satırları varsa şifresiz bağlantı bu yüzden eşleşmez. Çözüm, bu dört bilgiyi kapsayan bir satır eklemek ya da doğru veritabanına bağlanmaktır. Dosyanın okunmuş hâlini ve satır hatalarını pg_hba_file_rules görünümünden görebilirsiniz:

sql
SELECT line_number, type, database, user_name, address, auth_method, error
FROM pg_hba_file_rules;
text
 line_number | type |  database   | user_name  |  address  |  auth_method  | error 
-------------+------+-------------+------------+-----------+---------------+-------
           1 | host | {all}       | {postgres} | 127.0.0.1 | trust         | 
           2 | host | {ornek_upg} | {uygulama} | 127.0.0.1 | scram-sha-256 | 
(2 rows)

Birinci satırdaki trust yalnızca bu yerel deneme kümesi içindir; gerçek bir sunucuda kullanmayın. Satır biçimi, sıranın önemi ve yöntemler pg_hba.conf ve uzak bağlantı yazısında ayrıntılı anlatılıyor. Bir başka ince nokta: var olmayan bir kullanıcı adıyla denediğimizde de mesaj no pg_hba.conf entry for host "127.0.0.1", user "olmayan_kullanici", database "ornek_upg", no encryption oldu, çünkü kural yalnızca uygulama rolüne yazılmıştı. Yani bu mesaj rolün var olup olmadığını söylemez.

password authentication failed

Kılavuza göre bu mesaj sunucuya ulaştığınızı ve sunucunun sizinle konuşmaya istekli olduğunu, ama önce pg_hba.conf'taki yöntemi geçmeniz gerektiğini gösterir. Yanlış parolayla:

text
psql: error: connection to server at "127.0.0.1", port 46481 failed: FATAL:  password authentication failed for user "uygulama"

İstemciye giden mesaj kasıtlı olarak kısadır. Kılavuzun ipucu: kimlik doğrulama hatası hakkında sunucu logunda istemciye bildirilenden daha fazla bilgi bulunabilir. Logumuzda aynı deneme için bir DETAIL satırı vardı ve hangi dosyanın hangi satırının eşleştiğini gösteriyordu (dosya yolu kısaltıldı):

text
FATAL:  password authentication failed for user "uygulama"
DETAIL:  Connection matched file ".../hedef/pg_hba.conf" line 2: "host    ornek_upg  uygulama   127.0.0.1/32   scram-sha-256"

Kontrol edilecekler: parolanın doğruluğu, rolün gerçekten bir parolası olup olmadığı (ALTER ROLE uygulama PASSWORD '...'), eşleşen satırın beklediğiniz satır olup olmadığı. PostgreSQL 18 sürüm notlarına göre MD5 parola doğrulaması kullanımdan kaldırılma yolundadır; yeni kurulumlarda scram-sha-256 kullanın. Parolaları komut satırına yazmak yerine libpq'nun okuduğu ~/.pgpass parola dosyasını kullanabilirsiniz. Rol ve parola işlemleri kullanıcı ve rol yönetimi yazısında.

role does not exist ve database does not exist

Kural eşleştikten sonra sunucu rolün ve veritabanının varlığını kontrol eder. Var olmayan bir veritabanına bağlanmayı denediğimizde:

text
psql: error: connection to server at "127.0.0.1", port 46481 failed: FATAL:  database "olmayan_db" does not exist

Kılavuz sık rastlanan bir tuzağa dikkat çeker: veritabanı adı verilmezse varsayılan olarak kullanıcı adıyla aynı adlı veritabanına bağlanılır. psql -U uygulama yazıp -d vermezseniz uygulama adlı bir veritabanı aranır. Rol tarafında ise yukarıda gördüğünüz role "egeme" does not exist satırı aynı mantıkla ortaya çıktı: kullanıcı adı verilmeyince istemci işletim sistemi kullanıcısının adını kullandı. Mevcut veritabanlarını psql'de \l, rolleri \du ile listeleyebilirsiniz; bkz. psql komutları.

too many clients already

Sunucunun eşzamanlı bağlantı sayısı max_connections ile sınırlıdır; kılavuza göre varsayılan genellikle 100'dür ve parametre yalnızca sunucu başlarken ayarlanır. Bu yuvaların bir kısmı ayrılmıştır: superuser_reserved_connections (varsayılan 3) süper kullanıcılar için son acil durum rezervidir, reserved_connections (varsayılan 0) ise pg_use_reserved_connections yetkisine sahip roller içindir. Davranışı görmek için deneme kümesinde max_connections = 4 ve superuser_reserved_connections = 1 ayarlayıp sunucuyu yeniden başlattık, sonra uygulama rolüyle üç bağlantı açık tuttuk. Dördüncü normal bağlantı:

text
psql: error: connection to server at "127.0.0.1", port 46481 failed: FATAL:  remaining connection slots are reserved for roles with the SUPERUSER attribute

Kalan son yuvayı bir süper kullanıcı bağlantısı aldıktan sonra beşinci deneme, süper kullanıcıyla bile şu mesajı verdi:

text
psql: error: connection to server at "127.0.0.1", port 46481 failed: FATAL:  sorry, too many clients already

Ayrılmış yuvalar bu yüzden değerlidir: uygulama tüm normal yuvaları doldurduğunda yönetici hâlâ bağlanıp sorunu inceleyebilir. Açık bağlantıları pg_stat_activity ile sayın:

sql
SELECT count(*) AS istemci, current_setting('max_connections') AS en_fazla,
       current_setting('superuser_reserved_connections') AS ayrilan
FROM pg_stat_activity WHERE backend_type = 'client backend';
text
 istemci | en_fazla | ayrilan 
---------+----------+---------
       1 | 100      | 3
(1 row)

Kılavuz max_connections değerini artırmanın paylaşılan bellek dahil bazı kaynakların daha fazla ayrılmasına yol açtığını belirtir; yani sınırı yükseltmek bedelsiz değildir. Önce boşta bekleyen veya sızan bağlantıları bulun, uzun süredir bekleyen oturumları sonlandırmayı düşünün (pg_stat_activity ile izleme). Çok sayıda kısa ömürlü bağlantı açan uygulamalarda bağlantı havuzu kullanımı genel performans konusu olarak PostgreSQL performans optimizasyonu yazısında ele alınıyor.

Adım adım teşhis

Adım adım teşhis: pg_isready -h ADRES -p PORT -U ROL çalıştırın. Çıkış kodu 2 ise TCP..., Kod 0 ama bağlantı başarısızsa mesaj FATAL ile başlar ve kimlik doğrulama veya..., no...
  • pg_isready -h ADRES -p PORT -U ROL çalıştırın. Çıkış kodu 2 ise TCP düzeyindesiniz: sunucu, port, listen_addresses, güvenlik duvarı.
  • Kod 0 ama bağlantı başarısızsa mesaj FATAL ile başlar ve kimlik doğrulama veya yuva aşamasındasınız.
  • no pg_hba.conf entry için mesajdaki adres, kullanıcı, veritabanı ve şifreleme bilgisini pg_hba_file_rules ile karşılaştırın.
  • password authentication failed için sunucu logundaki DETAIL satırını okuyun.
  • Yapılandırma değiştirdiyseniz değişikliğin etkin olup olmadığını kontrol edin: pg_hba.conf yeniden yükleme ister, listen_addresses ve max_connections yeniden başlatma ister. Parametre bağlamları postgresql.conf ve ALTER SYSTEM yazısında.

Sık Sorulan Sorular

Sunucu çalışıyor, yerelden bağlanıyorum ama uzaktan connection refused alıyorum. Neden?

En olası neden listen_addresses değerinin varsayılan localhost olarak kalmasıdır. Sunucu yalnızca loopback arayüzünü dinler. Parametreyi değiştirip sunucuyu yeniden başlatın, ardından uzak adres için pg_hba.conf satırı ekleyin.

Hata kodunu (SQLSTATE) bağlantı hatalarında da görebilir miyim?

Evet; bağlantı hataları da kod taşır. Örneğin kılavuzun hata kodları ekinde 28P01 invalid_password, 53300 too_many_connections ve sınıf 08 bağlantı istisnaları listelenir. Sürücünüz bu kodu ayrı bir alan olarak verir; ayrıntı SQLSTATE kodları yazısında.

pg_hba.conf'u değiştirdim ama hiçbir şey değişmedi.

Dosya otomatik okunmaz; SELECT pg_reload_conf(); veya pg_ctl reload ile yeniden yükleyin ve pg_hba_file_rules görünümünün error sütununda satır hatası olup olmadığına bakın.

PHP uygulamam bağlanamıyor, psql bağlanıyor.

İki istemcinin aynı adres, port, kullanıcı ve veritabanını kullandığını kontrol edin; mesajdaki adres ve kullanıcı bilgisi farkı genellikle gösterir. PHP tarafındaki bağlantı dizesi için PHP PDO veritabanı bağlantısı yazısına bakın.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: PostgreSQL öğrenme rehberi · pg_hba.conf ve uzak bağlantı · SSL/TLS bağlantı · SQLSTATE kodları · pg_stat_activity · SSH ile sunucuya bağlanma