Error Umum #

Sebagian besar masalah Nginx di lingkungan produksi jatuh ke dalam kategori galat (error) yang sama secara berulang kali. Kemampuan mengenali pola-pola galat ini membuat diagnosis masalah menjadi jauh lebih cepat. Alih-alih memulai proses investigasi dari nol setiap kali terjadi kendala, kita dapat langsung mengarah ke akar penyebab yang paling sering terjadi berdasarkan pesan log yang tercatat.

Di artikel ini, kita akan membahas secara mendalam berbagai galat HTTP yang paling sering ditemui di Nginx, cara membaca pesan log kesalahannya, langkah investigasi sistematis untuk setiap kasus, serta solusi praktis untuk mengatasinya.

Diagram Keputusan Respons Status Nginx #

Sebelum membedah setiap galat satu per satu, kita perlu memahami bagaimana Nginx memutuskan untuk mengirimkan kode status respons tertentu ke browser klien. Berikut adalah diagram alur keputusan penentuan status respons di Nginx:

flowchart TD
    Req["Request Tiba di Nginx"] --> Match{"Apakah Cocok Rute?"}
    Match -->|"Tidak"| Err404["HTTP 404 Not Found<br/>(Cek root/alias & try_files)"]
    Match -->|"Ya"| Auth{"Butuh Otorisasi / IP Whitelist?"}
    
    Auth -->|"Ditolak / Izin File Kurang"| Err403["HTTP 403 Forbidden<br/>(Cek chown/chmod & allow/deny)"]
    Auth -->|"Lolos"| Size{"Apakah Request Body > limit?"}
    
    Size -->|"Ya"| Err413["HTTP 413 Request Entity Too Large<br/>(Cek client_max_body_size)"]
    Size -->|"Tidak"| Conn{"Koneksi ke Backend Upstream"}
    
    Conn -->|"Backend Mati / Salah Port"| Err502["HTTP 502 Bad Gateway<br/>(Connection Refused / Closed)"]
    Conn -->|"Backend Lambat merespons"| Err504["HTTP 504 Gateway Timeout<br/>(proxy_read_timeout exceeded)"]
    Conn -->|"Respons Berhasil"| OK["HTTP 200 OK"]

    classDef default fill:#f9f9f9,stroke:#d1d5db,stroke-width:1px,color:#111827;
    classDef errStyle fill:#fef2f2,stroke:#ef4444,stroke-width:2px,color:#991b1b;
    classDef okStyle fill:#f0fdf4,stroke:#15803d,stroke-width:2px,color:#166534;
    class Err404,Err403,Err413,Err502,Err504 errStyle;
    class OK okStyle;

HTTP 502 Bad Gateway #

Galat 502 Bad Gateway mengindikasikan bahwa Nginx bertindak sebagai proxy yang berhasil menerima permintaan dari klien, tetapi ketika mencoba meneruskannya ke server aplikasi backend (seperti Node.js, PHP-FPM, atau Python Gunicorn), Nginx menerima respons yang tidak valid atau tidak menerima respons sama sekali (koneksi terputus/ditolak).

1. Anatomi Pesan Error Log #

Ketika galat 502 terjadi, kita harus segera memeriksa berkas error log Nginx. Berikut adalah variasi pesan error log yang sering muncul beserta interpretasinya:

  • connect() failed (111: Connection refused) while connecting to upstream
    • Arti: Nginx mencoba menghubungi alamat IP dan port backend, tetapi sistem operasi menolak koneksi tersebut karena tidak ada proses yang mendengarkan (listening) pada port target.
  • connect() failed (2: No such file or directory) while connecting to upstream
    • Arti: Terjadi saat kita menggunakan Unix Domain Socket (misal .sock file), namun berkas socket fisik tersebut tidak ada di disk server.
  • recv() failed (104: Connection reset by peer) while reading response header from upstream
    • Arti: Nginx berhasil terhubung ke backend, tetapi backend secara tiba-tiba memutuskan koneksi TCP saat Nginx sedang menunggu data header respons dikirimkan. Ini biasanya terjadi karena backend crash (mati mendadak) akibat kehabisan memori (out of memory) atau error fatal pada kode aplikasi.

2. Langkah Investigasi Sistematis #

Jika kita mendapati galat 502 di server kita, lakukan langkah-langkah berikut:

  • Langkah 1: Periksa apakah proses aplikasi backend sedang berjalan.
    # Untuk PHP-FPM
    sudo systemctl status php8.2-fpm
    
    # Untuk Node.js yang dikelola PM2
    pm2 status
    
    # Untuk Python Gunicorn/Uvicorn yang dikelola systemd
    sudo systemctl status gunicorn
    
  • Langkah 2: Jika proses berjalan, periksa port atau socket yang digunakan oleh backend tersebut. Pastikan port tersebut sama dengan yang kita tulis di direktif proxy_pass atau fastcgi_pass Nginx.
    # Periksa port TCP yang sedang listen
    sudo ss -tlnp | grep -E "3000|8000|9000"
    
    # Periksa apakah berkas Unix socket ada
    ls -la /run/php/php8.2-fpm.sock
    
  • Langkah 3: Lakukan pengujian koneksi langsung ke backend melewati localhost server menggunakan utilitas curl untuk mengisolasi peran Nginx:
    curl -I http://127.0.0.1:3000/
    
    Jika perintah di atas mengembalikan respons sukses, berarti masalah ada pada jalur komunikasi Nginx ke backend (misalnya masalah hak akses socket atau konfigurasi IP). Jika curl langsung gagal, berarti aplikasi backend kita yang memang bermasalah.

3. Solusi Praktis #

  • Gunakan konfigurasi cadangan (failover): Jika kita menggunakan cluster backend, pastikan Nginx tidak terus mengirimkan request ke node yang mati menggunakan parameter max_fails dan fail_timeout pada blok upstream.
  • Perbaiki hak akses Unix socket: Jika menggunakan socket, pastikan user sistem Nginx (www-data) memiliki izin membaca dan menulis berkas socket tersebut.
    # Contoh perbaikan kepemilikan socket PHP-FPM
    sudo chown www-data:www-data /run/php/php8.2-fpm.sock
    sudo chmod 660 /run/php/php8.2-fpm.sock
    

HTTP 504 Gateway Timeout #

Galat 504 Gateway Timeout berarti Nginx berhasil terhubung ke server backend upstream, tetapi backend tersebut membutuhkan waktu terlalu lama untuk memproses permintaan klien dan tidak mengirimkan respons apa pun dalam batas waktu (timeout) yang ditentukan oleh konfigurasi Nginx.

1. Anatomi Pesan Error Log #

Pesan error log yang tercatat untuk kasus 504 biasanya berbunyi:

2026/06/16 14:15:00 [error] 12345#12345: *998 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 203.0.113.50, server: app.unisbadri.com, request: "GET /api/export-data HTTP/1.1", upstream: "http://127.0.0.1:3000/api/export-data", host: "app.unisbadri.com"

2. Langkah Investigasi Sistematis #

  • Langkah 1: Periksa endpoint URL yang memicu error 504. Apakah request tersebut melibatkan query database yang sangat berat, pemrosesan file besar (seperti ekspor PDF/Excel), atau pemanggilan API eksternal pihak ketiga yang lambat?
  • Langkah 2: Periksa utilitas resource server saat request dikirimkan. Apakah CPU server melonjak hingga 100%? Apakah RAM habis sehingga memicu swap memori yang lambat?
    # Pantau penggunaan resource secara real-time
    htop
    
  • Langkah 3: Periksa log aplikasi backend kita untuk melihat berapa lama waktu yang dihabiskan oleh aplikasi untuk memproses request sebelum koneksi ditutup oleh Nginx.

3. Solusi Praktis #

  • Naikkan durasi timeout Nginx: Jika rute tertentu memang membutuhkan waktu pemrosesan yang lama (seperti generator laporan), kita wajib menaikkan timeout khusus untuk location block tersebut:
    location /api/export-data {
        proxy_pass http://nodejs_backend;
    
        # Naikkan batas waktu tunggu respons menjadi 5 menit (300 detik)
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
        proxy_connect_timeout 300s;
    }
    
  • Tuning Timeout FastCGI (untuk PHP-FPM):
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    
        # Naikkan timeout PHP FastCGI
        fastcgi_read_timeout 300s;
    }
    
    Catatan: Pastikan kita juga menaikkan konfigurasi max_execution_time di berkas php.ini milik PHP-FPM agar sejalan dengan timeout Nginx.

HTTP 403 Forbidden #

Galat 403 Forbidden menunjukkan bahwa server memahami apa yang ingin diakses oleh klien, tetapi server secara sadar menolak untuk memberikan akses tersebut karena masalah perizinan berkas (file permissions), larangan direktori index, atau aturan keamanan yang memblokir request.

1. Anatomi Pesan Error Log #

Pesan log untuk 403 sangat spesifik mengenai penyebabnya:

  • directory index of "/var/www/html/" is forbidden
    • Arti: Klien mengakses URL direktori (seperti / atau /images/), tetapi di dalam folder tersebut tidak ada file indeks default (seperti index.html atau index.php), sementara direktif autoindex (yang menampilkan daftar file) dalam kondisi nonaktif.
  • open() "/var/www/html/secret.txt" failed (13: Permission denied)
    • Arti: Berkas fisik ada di disk, tetapi user sistem yang menjalankan worker process Nginx (biasanya www-data atau nginx) tidak memiliki hak akses baca terhadap berkas tersebut atau folder induknya.

2. Langkah Investigasi Sistematis #

  • Langkah 1: Periksa apakah berkas index default (misalnya index.html) benar-benar ada di dalam direktori root aplikasi kita.
  • Langkah 2: Periksa hak kepemilikan (ownership) dan hak akses (permissions) berkas serta folder target.
    ls -la /var/www/html/
    
  • Langkah 3: Periksa apakah ada aturan keamanan aktif seperti modul allow/deny di konfigurasi Nginx kita yang tidak sengaja memblokir IP klien kita.
  • Langkah 4: Jika menggunakan distro berbasis RedHat (CentOS/RHEL/Fedora), periksa status keamanan SELinux. SELinux sering kali memblokir akses Nginx ke folder di luar standar /usr/share/nginx/html.

3. Solusi Praktis #

  • Perbaiki hak akses berkas secara rekursif: Pastikan direktori memiliki permission 755 (bisa diakses dan dilalui) dan berkas memiliki permission 644 (bisa dibaca klien, hanya ditulis oleh owner):
    # Ubah kepemilikan ke user Nginx
    sudo chown -R www-data:www-data /var/www/html/
    
    # Setel permission folder ke 755
    sudo find /var/www/html/ -type d -exec chmod 755 {} \;
    
    # Setel permission berkas ke 644
    sudo find /var/www/html/ -type f -exec chmod 644 {} \;
    
  • Konfigurasikan konteks SELinux:
    # Izinkan Nginx membaca berkas di folder kustom
    sudo chcon -Rt httpd_sys_content_t /var/www/html/
    
  • Aktifkan autoindex (hanya untuk folder unduhan/publik):
    location /downloads/ {
        autoindex on; # Menampilkan daftar file di browser klien
    }
    

HTTP 404 Not Found #

Galat 404 Not Found berarti Nginx tidak dapat menemukan berkas atau resource fisik yang diminta oleh browser klien pada direktori root yang telah dikonfigurasi.

1. Anatomi Pesan Error Log #

Pesan log untuk 404 biasanya berbunyi:

2026/06/16 14:20:00 [error] 12345#12345: *1002 open() "/var/www/html/dashboard" failed (2: No such file or directory), client: 203.0.113.50, server: app.unisbadri.com, request: "GET /dashboard HTTP/1.1", host: "app.unisbadri.com"

2. Langkah Investigasi Sistematis #

  • Langkah 1: Periksa berkas error log Nginx untuk melihat letak path fisik di mana Nginx mencoba mencari berkas tersebut. Pada contoh log di atas, Nginx mencari berkas bernama dashboard di dalam folder /var/www/html/.
  • Langkah 2: Periksa direktif root atau alias pada file konfigurasi virtual host. Kesalahan ketik satu karakter pada path root akan membuat Nginx mencari di folder yang salah.
  • Langkah 3: Periksa apakah rute tersebut adalah rute dinamis milik Single Page Application (React/Vue). Jika ya, Nginx secara fisik memang tidak memiliki file /dashboard di disk karena routing diatur di browser klien.

3. Solusi Praktis #

  • Implementasikan fallback routing untuk SPA: Pastikan kita menyertakan direktif try_files agar request dialihkan kembali ke berkas index.html utama:
    location / {
        root /var/www/my-spa-app/dist;
        try_files $uri $uri/ /index.html;
    }
    
  • Periksa Trailing Slash pada Proxy Pass: Ingat aturan trailing slash. Jika kita menulis:
    location /api {
        proxy_pass http://backend/; # Trailing slash di akhir
    }
    
    Request ke /api/users akan diteruskan ke backend sebagai /users (karakter /api dibuang). Ini sering memicu error 404 di sisi server backend aplikasi kita. Pastikan penulisan lokasi dan target proxy sinkron.

HTTP 413 Request Entity Too Large #

Galat 413 Request Entity Too Large terjadi saat browser klien mencoba mengirimkan data request body (seperti unggahan berkas gambar atau video) yang ukurannya melebihi batas maksimal yang diizinkan oleh konfigurasi Nginx.

1. Anatomi Pesan Error Log #

Pesan log untuk 413 berbunyi:

2026/06/16 14:22:00 [warn] 12345#12345: *1015 client intended to send too large body: 15485724 bytes, client: 203.0.113.50, server: app.unisbadri.com, request: "POST /api/upload HTTP/1.1", host: "app.unisbadri.com"

2. Solusi Praktis #

Secara default, Nginx membatasi ukuran request body klien sebesar 1 Megabyte. Untuk mengizinkan unggahan file berukuran besar, kita harus menaikkan batas ini menggunakan direktif client_max_body_size.

Kita bisa menerapkannya di tingkat http global, server block, atau secara spesifik di location block pengunggahan:

server {
    listen 80;
    server_name app.unisbadri.com;

    # Batas default global untuk server block ini (10MB)
    client_max_body_size 10m;

    location /api/upload-video {
        # Batas kustom khusus untuk unggah video (500MB)
        client_max_body_size 500m;
        proxy_pass http://upload_backend;
    }
}

Masalah SSL/TLS Umum #

Masalah konfigurasi SSL/TLS di Nginx dapat mengakibatkan situs web kita tidak dapat diakses sama sekali dan menampilkan peringatan keamanan yang menakutkan bagi pengunjung.

1. Browser Error: ERR_SSL_PROTOCOL_ERROR atau SSL_ERROR_RX_RECORD_TOO_LONG #

  • Gejala: Browser gagal melakukan handshake SSL aman.
  • Penyebab paling umum: Kita mengonfigurasi Nginx untuk mendengarkan port HTTPS (443), tetapi lupa menyalakan direktif ssl pada baris listen tersebut, sehingga Nginx mengirimkan respons HTTP biasa lewat port HTTPS.
  • Solusi: Pastikan parameter ssl ditulis secara eksplisit di direktif listen:
    # Konfigurasi salah:
    listen 443;
    
    # Konfigurasi benar:
    listen 443 ssl http2;
    

2. Browser Error: ERR_CERT_AUTHORITY_INVALID (Sertifikat Tidak Tepercaya) #

  • Gejala: Browser menampilkan peringatan “Koneksi tidak privat (tidak aman)” dan menolak memuat halaman web.
  • Penyebab paling umum: Kita menggunakan sertifikat Let’s Encrypt atau CA publik lainnya, tetapi pada direktif ssl_certificate Nginx, kita hanya mengarahkan berkas ke sertifikat utama domain kita (cert.pem) tanpa menyertakan sertifikat intermediate CA. Hal ini membuat rantai kepercayaan (Chain of Trust) terputus di browser klien.
  • Solusi: Selalu gunakan berkas fullchain.pem (yang menggabungkan sertifikat domain kita dan intermediate CA) pada setelan Nginx kita:
    # Salah:
    ssl_certificate /etc/letsencrypt/live/app.unisbadri.com/cert.pem;
    
    # Benar:
    ssl_certificate /etc/letsencrypt/live/app.unisbadri.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.unisbadri.com/privkey.pem;
    

3. Browser Error: ERR_CERT_COMMON_NAME_INVALID (Nama Tidak Cocok) #

  • Gejala: Browser memperingatkan bahwa sertifikat keamanan bukan milik domain situs kita.
  • Penyebab paling umum: Nilai server_name yang diakses oleh klien tidak terdaftar di dalam kolom Subject Alternative Name (SAN) sertifikat SSL aktif kita.
  • Solusi: Pastikan kita meminta sertifikat SSL yang mencakup domain utama beserta sub-domain wildcard (jika diperlukan) menggunakan Certbot, dan arahkan berkas sertifikat yang benar pada server block yang bersesuaian.

4. Cara Memeriksa Detail Sertifikat via CLI #

Kita bisa mendiagnosis masalah SSL langsung dari terminal tanpa membuka browser menggunakan perintah utilitas OpenSSL berikut:

# Menampilkan detail subjek, penerbit sertifikat, dan tanggal kedaluwarsa
echo | openssl s_client -connect app.unisbadri.com:443 -servername app.unisbadri.com 2>/dev/null | \
    openssl x509 -noout -text | grep -E "Subject:|Issuer:|Not After:|DNS:"

Nginx Tidak Mau Start / Reload #

Terkadang Nginx menolak untuk memulai ulang (restart) atau memperbarui konfigurasi (reload) karena konflik jaringan atau file sistem.

1. Port 80 atau 443 Sudah Digunakan (Address already in use) #

  • Gejala: Nginx gagal start dan log sistem menampilkan pesan galat: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
  • Penyebab: Ada software web server lain (seperti Apache apache2 atau Caddy) yang sedang berjalan di port yang sama.
  • Langkah Diagnosis & Solusi:
    • Temukan proses apa yang sedang menduduki port 80/443:
      sudo ss -tlnp | grep -E ":80|:443"
      # Output akan menampilkan PID dan nama proses (misal: apache2)
      
    • Matikan proses web server saingan tersebut dan nonaktifkan layanannya agar tidak berjalan saat reboot:
      sudo systemctl stop apache2
      sudo systemctl disable apache2
      
    • Nyalakan kembali Nginx:
      sudo systemctl start nginx
      

2. Berkas PID Hilang atau Corrupt #

  • Gejala: Jalankan nginx -s reload menghasilkan error nginx: [error] open() "/run/nginx.pid" failed (2: No such file or directory).
  • Penyebab: Nginx tidak sedang berjalan di memori server, atau berkas PID terhapus secara sengaja oleh proses pembersihan sementara.
  • Solusi: Jalankan perintah start secara bersih alih-alih melakukan reload:
    sudo systemctl start nginx
    

Ringkasan Langkah Mitigasi Cepat #

  • Investigasi 502 (Bad Gateway): Periksa apakah proses aplikasi backend kita mati. Gunakan curl -I localhost:PORT untuk memastikan port backend merespons.
  • Investigasi 504 (Gateway Timeout): Naikkan direktif proxy_read_timeout dan fastcgi_read_timeout di Nginx untuk URL yang berat, serta optimalkan query database backend kita.
  • Investigasi 403 (Forbidden): Periksa keselarasan izin akses berkas dan kepemilikan oleh user www-data. Pastikan direktori root memiliki berkas indeks seperti index.html.
  • Investigasi 404 (Not Found): Cek path direktori fisik pada direktif root. Tambahkan try_files untuk fallback routing pada Single Page Application (SPA).
  • Gunakan fullchain.pem: Selalu gunakan sertifikat chain lengkap untuk setelan ssl_certificate guna menangkal galat rantai kepercayaan browser yang putus.
  • Jalankan nginx -t: Biasakan selalu memvalidasi berkas konfigurasi sebelum melakukan reload untuk mencegah downtime pada server produksi.

← Sebelumnya: WebSocket Proxying   Berikutnya: Debug Konfigurasi →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact