Nginx 502 Bad Gateway hatası, Nginx’in isteği ilettiği arka uç uygulamadan (upstream) geçerli bir HTTP yanıtı alamadığını gösterir. Bu arka uç; PHP-FPM, Node.js, Python/Gunicorn, Java uygulaması, Apache veya başka bir proxy sunucusu olabilir. Sorun yalnızca belirli bir siteyi, belirli URL’leri ya da tüm sanal sunucuyu etkileyebilir. Güvenli çözüm, doğrudan servisleri yeniden başlatmak yerine önce Nginx hata günlüğündeki upstream mesajını okuyup bağlantı noktası, soket, uygulama sağlığı ve kaynak kullanımını sırayla doğrulamaktır.
Bu rehber, Linux üzerinde Nginx’in PHP-FPM veya HTTP tabanlı bir uygulama sunucusuna bağlanırken ürettiği 502 yanıtlarını çözmeye odaklanır. 502 ile 504 aynı değildir: 502 genellikle bağlantının reddedilmesi, soketin bulunamaması veya uygulamanın geçersiz/yarım yanıt vermesiyle ilişkilidir; 504 ise arka ucun yanıtının Nginx zaman aşımı süresini geçmesiyle görülür.
Nginx 502 Bad Gateway hatasının belirtileri ve kapsamı
Tarayıcıda 502 sayfası görünürken Nginx çoğunlukla çalışır durumdadır; sorun Nginx’in arkasındaki bileşendedir. Etki alanını belirlemek, yanlış servisi yeniden başlatmayı veya çalışan sitelerde kesinti oluşturmayı önler.
- Tek bir alan adı etkileniyorsa: İlgili virtual host, uygulama havuzu, PHP-FPM pool’u veya o uygulamanın soketi incelenmelidir.
- Tüm PHP siteleri etkileniyorsa: PHP-FPM servisi, ortak soket dizini, disk alanı veya sistem kaynakları önceliklidir.
- Yalnızca dinamik URL’ler etkileniyorsa: Statik dosyaları Nginx sunabilir; arıza büyük olasılıkla FastCGI ya da uygulama upstream’indedir.
- Aralıklı oluşuyorsa: OOM (bellek yetersizliği), yoğunluk, süreç çökmesi, bağlantı limiti veya uzun süren uygulama istekleri araştırılmalıdır.
Nginx 502 Bad Gateway hatası için hızlı teşhis özeti
- Hatanın zamanını, etkilenen URL’yi ve tekil mi yaygın mı olduğunu kaydedin.
- Nginx error log içindeki
upstreamsatırını bulun. - Etkin Nginx yapılandırmasında gerçek
fastcgi_passveyaproxy_passhedefini doğrulayın. - Arka uç servisinin çalıştığını, dinleme soketi/portunun var olduğunu ve yerelden yanıt verdiğini test edin.
- Disk, bellek, OOM günlükleri ve güvenlik politikalarını kontrol edin.
- Yalnızca kanıtın gösterdiği bileşene, kontrollü değişiklik uygulayın; ardından yapılandırma testi ve HTTP testi yapın.
Önemli: Yapılandırma değişikliği, paket güncellemesi, pool ayarı veya uygulama dağıtımı öncesinde çalışan yapılandırmanın ve uygulama dosyalarının yedeğini alın. Üretim ortamında servis yeniden başlatma veya güncelleme işlemlerini bakım penceresinde planlayın. PHP-FPM yeniden başlatılması, devam eden dinamik istekleri etkileyebilir.
Log mesajına göre olası nedenler
| Nginx hata günlüğü örneği | Muhtemel neden | İlk güvenli kontrol |
|---|---|---|
connect() to unix:... failed (2: No such file or directory) |
PHP-FPM soketi yok veya Nginx yanlış soket yoluna bakıyor. | PHP-FPM durumu ve aktif listen değeri |
connect() ... failed (111: Connection refused) |
Upstream durmuş, yanlış port kullanılıyor veya uygulama dinlemiyor. | Servis durumu ve ss çıktısı |
connect() ... failed (13: Permission denied) |
Soket dosyası izinleri ya da SELinux erişimi engelliyor. | Soket sahibi/kipleri ve audit kayıtları |
upstream prematurely closed connection |
Uygulama/PHP-FPM isteği tamamlamadan kapandı; çökme veya kaynak sorunu olabilir. | Uygulama günlüğü, PHP-FPM günlüğü, OOM kayıtları |
recv() failed (104: Connection reset by peer) |
Arka uç bağlantıyı sıfırladı; süreç yeniden başladı veya uygulama hatası oluştu. | Servis ve uygulama hata günlükleri |
Loglar ve etkin yapılandırma ile teşhis
1. Nginx hata günlüğündeki upstream satırını bulun
Günlük yolu dağıtıma ve Nginx yapılandırmasına göre değişebilir. Yaygın kurulumlarda ana hata günlüğü aşağıdaki konumdadır; ancak kesin yolu etkin yapılandırmadan teyit edin.
sudo tail -n 100 /var/log/nginx/error.log
sudo grep -iE 'upstream|connect\(|prematurely|reset' /var/log/nginx/error.log | tail -n 50
Sistem günlüklerini systemd üzerinden de inceleyin:
sudo journalctl -u nginx --since '30 minutes ago' --no-pager
2. Nginx’in gerçekten hangi upstream hedefini kullandığını doğrulayın
Yalnızca dosya adlarına bakmak yeterli değildir; dahil edilen yapılandırmalar farklı bir hedef tanımlayabilir. Etkin yapılandırmayı sözdizimiyle birlikte görüntüleyin:
sudo nginx -T
Çıktıda etkilenen server bloğundaki fastcgi_pass, proxy_pass veya adlandırılmış upstream bölümünü bulun. Örneğin Nginx bir Unix soketine yöneliyorsa, PHP-FPM’in listen değeri bu yol ile birebir aynı olmalıdır. TCP upstream kullanılıyorsa IP adresi ve port da eşleşmelidir.
3. Servis, soket ve port durumunu kontrol edin
PHP-FPM servis adı sürüm ve dağıtıma göre değişir. Debian/Ubuntu’da ad genellikle php8.x-fpm, RHEL türevlerinde ise çoğu kurulumda php-fpm olur. Sunucunuzdaki gerçek birimi listeleyin:
systemctl list-units --type=service --all 'php*-fpm.service'
sudo systemctl status php-fpm
sudo systemctl status php8.2-fpm
Son iki komuttan yalnızca sisteminizde bulunan servis adına ait olanı kullanın. Unix soketleri ve TCP dinleyicileri için:
sudo ss -xlpn
sudo ss -ltnp
Bir uygulama TCP ile örneğin yerel bir porta yönlendiriliyorsa, doğrudan yerelden HTTP yanıtını test edin. Aşağıdaki örnekteki portu, etkin proxy_pass hedefinizdeki portla değiştirin:
curl -i --max-time 10 http://127.0.0.1:3000/
Bu istek de başarısızsa Nginx ayarını değiştirmeden önce uygulama servisini ve uygulama günlüğünü inceleyin.
Adım adım güvenli çözüm
PHP-FPM durmuş veya soket oluşmamışsa
Önce PHP-FPM günlüğünde başlangıç veya çökme hatası olup olmadığını kontrol edin. Günlüklerin yeri paket ve yapılandırmaya göre değişebileceğinden systemd günlüğü güvenilir başlangıç noktasıdır:
sudo journalctl -u php-fpm --since '1 hour ago' --no-pager
sudo journalctl -u php8.2-fpm --since '1 hour ago' --no-pager
Hata yoksa ve doğru servis durmuşsa kontrollü olarak başlatın. Servis zaten çalışıyor ancak soket yoksa, günlükteki nedeni çözmeden körlemesine tekrar tekrar yeniden başlatmayın.
sudo systemctl start php-fpm
sudo systemctl status php-fpm --no-pager
Debian/Ubuntu’da sürümlü birim kullanılıyorsa php-fpm yerine doğruladığınız birim adını yazın. Başlangıç sonrası ss -xlpn ile soketin oluştuğunu yeniden kontrol edin.
Nginx ve PHP-FPM soket yolları uyuşmuyorsa
Nginx tarafındaki fastcgi_pass unix:/yol/soket.sock; değeri ile ilgili PHP-FPM pool yapılandırmasındaki listen = /yol/soket.sock değeri aynı olmalıdır. Debian/Ubuntu’da sürüm içeren soket yolları yaygındır; RHEL ailesinde kurulum tercihlerine göre farklı yol kullanılabilir. Bu nedenle internetten alınmış bir soket yolunu doğrudan kopyalamayın.
Doğru yolu belirledikten sonra önce Nginx yapılandırmasını test edin. Test başarılı olmadan reload uygulamayın:
sudo nginx -t
sudo systemctl reload nginx
PHP-FPM pool ayarını değiştirdiyseniz, değişikliğin devreye girmesi için yalnızca ilgili PHP-FPM servisini bakım penceresinde yeniden başlatın:
sudo systemctl restart php-fpm
Soket izinleri veya SELinux erişimi engelliyorsa
Permission denied mesajında önce gerçek soket izinlerini kontrol edin:
sudo ls -l /run/php/
sudo namei -l /run/php/ORNEK.sock
ORNEK.sock yerine Nginx hata günlüğünde görülen gerçek soket dosyasını kullanın. Kalıcı çözüm; ilgili PHP-FPM pool’unda Nginx çalışan kullanıcısının erişebileceği doğru sahiplik ve kiplerin tanımlanmasıdır. Dosya üzerinde geçici chmod 777 kullanmak güvenli değildir ve servis yeniden başladığında zaten kaybolabilir.
SELinux etkin RHEL türevlerinde reddedilen erişimleri inceleyin:
getenforce
sudo ausearch -m AVC -ts recent
Nginx uzak bir TCP upstream’e bağlanacaksa, ortam politikanıza uygunsa HTTPD alanı için ağ bağlantısı izni gerekebilir. Bu değişiklik tüm web servis süreçlerini etkileyebileceği için önce güvenlik politikanızı değerlendirin:
sudo setsebool -P httpd_can_network_connect on
Unix soketindeki erişim reddi için bu boolean doğru çözüm olmayabilir; AVC kaydında hedef türü ve reddedilen işlemi esas alın.
Bellek, disk veya uygulama çökmesi varsa
Arka uç süreçlerinin işletim sistemi tarafından sonlandırılması 502 üretir. Özellikle upstream prematurely closed connection sonrasında OOM kayıtlarını inceleyin:
free -h
df -h
df -i
sudo journalctl -k --since '1 hour ago' | grep -iE 'out of memory|killed process|oom'
Disk doluluğu, inode tükenmesi veya bellek baskısı bulunursa önce sebebi belirleyin: büyüyen log, başarısız yedek, hatalı kuyruk işi, uygulama döngüsü ya da yetersiz kaynak gibi. Rastgele log silmek yerine uygulamanın log rotasyonunu ve alan tüketen dosyaları doğrulayın. Kaynak sorunu giderilmeden sadece PHP-FPM’i yeniden başlatmak, 502’nin kısa süre sonra geri dönmesine neden olabilir.
HTTP upstream yanıt veriyor ancak 502 devam ediyorsa
Uygulamayı Nginx’in gönderdiği Host başlığıyla test etmek, yanlış virtual host veya uygulama yönlendirmesini ortaya çıkarabilir:
curl -i --max-time 10 -H 'Host: alanadiniz.example' http://127.0.0.1:3000/
Yanıt burada geçerliyse, proxy_pass hedefi, proxy başlıkları ve Nginx error log’daki kesin hata yeniden karşılaştırılmalıdır. Uygulama yalnızca bazı isteklerde kapanıyorsa uygulama hata günlüğü, dağıtım geçmişi ve bağımlılık bağlantıları incelenmelidir.
Çözümün doğrulanması
Değişiklikten sonra hem yapılandırmayı hem de gerçek HTTP akışını doğrulayın:
sudo nginx -t
curl -I --max-time 15 http://127.0.0.1/
curl -Ik --max-time 15 https://alanadiniz.example/
HTTPS testindeki -k seçeneği yalnızca yerel teşhis amacıyla sertifika doğrulamasını atlar; normal izleme kontrollerinde kullanmayın. Ardından erişim ve hata günlüklerini kısa süre takip edin:
sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log
Beklenen sonuç, etkilenen URL’nin 2xx veya uygulamanın tasarladığı yönlendirme yanıtını vermesi ve yeni upstream hata satırlarının oluşmamasıdır.
502 hatasının tekrarını önleme
- Nginx ve PHP-FPM yapılandırmalarını sürüm kontrolünde veya güvenli bir yedekleme düzeninde saklayın.
- Dağıtım sonrası
nginx -t, ilgili servis durumu ve kritik URL için HTTP sağlık kontrolü çalıştırın. - Disk alanı, inode, bellek, PHP-FPM süreçleri ve uygulama hata oranı için eşik tabanlı izleme kurun.
- Uygulama socket/port değişikliklerini Nginx değişikliğiyle birlikte ve bakım planı kapsamında devreye alın.
- SELinux’u kapatmak yerine reddedilen erişimin nedenini AVC kayıtlarından analiz edin.
Sonuç
Nginx 502 Bad Gateway hatası çoğu zaman Nginx’in kendisinden değil, erişemediği veya sağlıklı yanıt alamadığı upstream bileşeninden kaynaklanır. Hata günlüğündeki kesin mesaj, etkin fastcgi_pass/proxy_pass hedefi ve arka uç servisinin yerel sağlık testi birlikte değerlendirildiğinde; yanlış soket, durmuş PHP-FPM, izin engeli, uygulama çökmesi ve kaynak baskısı güvenli biçimde ayrıştırılabilir.
Sık sorulan sorular
502 hatasında Nginx’i yeniden başlatmak yeterli mi?
Genellikle hayır. Nginx çalışıyor olsa bile PHP-FPM veya uygulama sunucusu durmuş, erişilemez ya da hatalı yanıt üretiyor olabilir. Önce error log’daki upstream mesajını kontrol edin.
502 ile 504 Bad Gateway arasındaki fark nedir?
502, upstream’e bağlanamama veya geçersiz/erken kesilen yanıtı; 504 ise upstream’in belirlenen sürede yanıt vermemesini ifade eder. Zaman aşımı değerlerini artırmadan önce uygulamanın neden yavaşladığını inceleyin.
PHP-FPM soketini elle oluşturabilir miyim?
Hayır. Soket PHP-FPM tarafından oluşturulmalıdır. Eksikse servis durumu, pool yapılandırmasındaki listen değeri ve PHP-FPM günlüğündeki başlangıç hatası incelenmelidir.
chmod 777 ile soket iznini açmak sorunu çözer mi?
Geçici olarak belirtiyi gizleyebilir ancak ciddi güvenlik riski oluşturur. Doğru yöntem, PHP-FPM pool’unun soket sahibi, grubu ve erişim kipini Nginx çalışan kullanıcısına göre kontrollü düzenlemektir.
Uzak bir uygulama sunucusunda 502 görülürse güvenlik duvarını kontrol etmeli miyim?
Evet. Nginx ile uzak upstream arasındaki ağ yolu, hedef portun dinlemesi, güvenlik duvarı ve SELinux politikası kontrol edilmelidir. Ancak hata günlüğü bağlantı reddi mi, zaman aşımı mı yoksa izin reddi mi olduğunu önce gösterecektir.