Error Umum

Error Umum #

Mengetahui error yang paling sering terjadi dan cara mengatasinya bisa menghemat waktu berjam-jam troubleshooting. Artikel ini mengkompilasi error-error yang paling umum ditemui pengguna Caddy beserta solusinya yang sudah terbukti.

1. Port Already in Use #

Error: listen tcp :443: bind: address already in use
Error: listen tcp :80: bind: address already in use

Penyebab: Ada proses lain yang sudah menggunakan port 80 atau 443.

# Cari proses yang menggunakan port tersebut
sudo lsof -i :443
sudo lsof -i :80

# Atau dengan ss (lebih modern)
sudo ss -tlnp | grep -E ':80|:443'

# Output contoh:
# LISTEN 0 128 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=1234,fd=6))

# Hentikan proses yang menggunakan port
sudo systemctl stop nginx    # Jika Nginx
sudo systemctl stop apache2  # Jika Apache

# Atau kill proses langsung
sudo kill -9 1234  # Ganti dengan PID dari lsof output

# Mulai Caddy
sudo systemctl start caddy

2. Permission Denied di Port < 1024 #

Error: listen tcp :443: bind: permission denied

Penyebab: User non-root tidak bisa bind ke port di bawah 1024 (port privileged).

# Solusi 1: Berikan capability ke binary Caddy
sudo setcap cap_net_bind_service=+ep $(which caddy)

# Verifikasi
getcap $(which caddy)
# /usr/bin/caddy = cap_net_bind_service+ep

# Solusi 2: Jalankan sebagai root (tidak disarankan untuk production)
# sudo caddy run

# Solusi 3: Gunakan systemd dengan AmbientCapabilities
# /etc/systemd/system/caddy.service
# [Service]
# AmbientCapabilities=CAP_NET_BIND_SERVICE
# CapabilityBoundingSet=CAP_NET_BIND_SERVICE

3. TLS Certificate Error #

Error: obtaining certificate: ...
Error: ACME challenge failed
Error: HTTP-01 challenge: could not connect to CA

Penyebab beragam:

# Cek DNS — domain harus resolve ke IP server ini
dig +short example.com
# Harus mengembalikan IP server Caddy, bukan IP lain

# Cek apakah port 80 bisa diakses dari internet
# (HTTP-01 challenge memerlukan ini)
curl http://example.com/.well-known/acme-challenge/test 2>&1

# Cek firewall
sudo ufw status
sudo iptables -L -n | grep -E "80|443"

# Cek apakah ada CDN di depan (Cloudflare, dll.)
# Pastikan tidak di-proxy jika pakai HTTP-01
# Atau gunakan DNS challenge dengan plugin caddy-dns

# Test secara manual dengan Let's Encrypt staging
# Di Caddyfile global options:
# { acme_ca https://acme-staging-v02.api.letsencrypt.org/directory }

4. 502 Bad Gateway #

HTTP/1.1 502 Bad Gateway

Penyebab: Caddy tidak bisa koneksi ke backend.

# Cek apakah backend berjalan
curl http://localhost:3000/health
# Jika gagal: backend tidak berjalan atau tidak di port yang benar

# Cek status backend service
sudo systemctl status myapp
pm2 status  # Jika pakai PM2

# Cek apakah backend listen di port yang benar
sudo ss -tlnp | grep :3000

# Cek Caddy log untuk detail error
sudo journalctl -u caddy -n 50 | grep -i "502\|upstream\|dial"

# Cek koneksi manual
curl -v http://localhost:3000/

5. 504 Gateway Timeout #

HTTP/1.1 504 Gateway Timeout

Penyebab: Backend terlalu lambat merespons.

example.com {
    reverse_proxy backend:3000 {
        transport http {
            # Naikkan timeout (default 0 = tidak ada timeout)
            response_header_timeout 120s
            
            # Timeout untuk baca response body
            read_timeout 300s
            
            # Timeout untuk tulis request
            write_timeout 120s
        }
    }
}
# Identifikasi request mana yang lambat
cat /var/log/caddy/access.log | \
    jq 'select(.duration > 5) | {uri: .request.uri, duration: .duration}' | \
    head -20

6. Syntax Error di Caddyfile #

Error: parsing Caddyfile: ...
# Validasi Caddyfile sebelum reload
caddy validate --config /etc/caddy/Caddyfile

# Output jika valid:
# Valid configuration

# Output jika tidak valid:
# parsing Caddyfile tokens: Caddyfile:15: unrecognized directive: rverse_proxy
# (typo: 'rverse_proxy' seharusnya 'reverse_proxy')

# Cek dengan format JSON untuk error yang lebih detail
caddy adapt --config /etc/caddy/Caddyfile | jq . 2>&1 | head -50

7. TLS Handshake Error #

Error: TLS handshake error from ...: ...
tls: no certificate available
# Cek apakah sertifikat sudah ada
ls ~/.local/share/caddy/certificates/
# atau
ls /var/lib/caddy/.local/share/caddy/certificates/

# Cek status sertifikat
caddy trust  # Untuk local development cert

# Paksa reload sertifikat
sudo systemctl reload caddy

# Debug TLS secara detail
curl -v https://example.com 2>&1 | grep -E "SSL|TLS|certificate|error"

# Check certificate expiry
echo | openssl s_client -connect example.com:443 2>/dev/null | \
    openssl x509 -noout -dates

8. Too Many Redirects #

Browser: ERR_TOO_MANY_REDIRECTS

Penyebab umum: Loop redirect antara Caddy dan konfigurasi lain.

# Debug redirect chain
curl -L -v https://example.com 2>&1 | grep -E "Location:|< HTTP"

# Contoh masalah umum:
# Caddy redirect HTTP ke HTTPS
# Tapi load balancer di depan mengirim HTTP ke Caddy
# Caddy melihat HTTP dan redirect lagi → infinite loop

# Solusi: konfigurasi trusted_proxies
{
    servers {
        # Percayai load balancer untuk menentukan protokol asli
        trusted_proxies static 10.0.0.0/8
    }
}

example.com {
    # Caddy tidak akan redirect jika protokol dari proxy adalah HTTPS
    file_server
}

9. WebSocket Connection Failed #

WebSocket: Error during WebSocket handshake
WebSocket: Unexpected response code: 404
# Test WebSocket upgrade manual
curl -v \
    -H "Upgrade: websocket" \
    -H "Connection: Upgrade" \
    -H "Sec-WebSocket-Version: 13" \
    -H "Sec-WebSocket-Key: $(openssl rand -base64 16)" \
    https://example.com/ws

# Status 101 = WebSocket upgrade berhasil
# Status 404 = path /ws tidak ada di backend
# Status 400 = backend tidak support WebSocket upgrade

# Cek akses log untuk status code WebSocket requests
cat /var/log/caddy/access.log | \
    jq 'select(.request.headers.Upgrade != null) | {uri: .request.uri, status: .status}'

10. Rate Limit Terkena Terus #

HTTP/1.1 429 Too Many Requests
# Cek konfigurasi rate limit
# Apakah limit terlalu rendah?
# Apakah IP yang salah?

# Cek header X-RateLimit-* untuk info limit
curl -I https://api.example.com/ | grep -i "ratelimit\|retry"

# Jika IP internal terkena rate limit:
# Tambahkan whitelist untuk IP internal
api.example.com {
    @internal remote_ip 10.0.0.0/8 192.168.0.0/16
    
    # Jangan rate limit IP internal
    rate_limit {
        zone api {
            key     {remote_host}
            window  1m
            events  100
            exclude @internal  # Skip untuk IP internal
        }
    }
}

Ringkasan #

  • Port already in use: cari proses dengan sudo lsof -i :443 dan hentikan sebelum start Caddy.
  • 502 Bad Gateway: hampir selalu berarti backend tidak berjalan — cek dengan curl localhost:PORT.
  • TLS errors: cek DNS dulu (domain harus resolve ke IP server), lalu pastikan port 80 bisa diakses dari internet untuk HTTP-01 challenge.
  • Too many redirects: biasanya karena loop dengan load balancer di depan — konfigurasi trusted_proxies dengan IP load balancer.
  • Selalu gunakan caddy validate sebelum reload konfigurasi — lebih baik menangkap error sebelum deploy daripada setelah.
  • Aktifkan debug log sementara ({ debug } di global options) untuk melihat detail lengkap saat troubleshooting masalah yang sulit.

← Sebelumnya: API Gateway   Berikutnya: Debug Config →


11. Caddy Tidak Bisa Menulis Sertifikat #

Error: open /var/lib/caddy/.local/share/caddy/certificates/...: permission denied

Penyebab: User caddy tidak punya akses ke direktori storage sertifikat.

# Cek permission direktori storage
ls -la /var/lib/caddy/

# Fix permission
sudo chown -R caddy:caddy /var/lib/caddy/
sudo chmod 750 /var/lib/caddy/

# Verifikasi Caddy bisa menulis
sudo -u caddy touch /var/lib/caddy/.local/share/caddy/test-write && echo "OK"

12. Caddy Tiba-tiba Berhenti #

# Cek kenapa Caddy berhenti
sudo journalctl -u caddy --since "1 hour ago" | tail -50

# Cek apakah ada OOM killer yang membunuh Caddy
sudo dmesg | grep -i "oom\|killed"

# Cek memory usage sebelum crash
sudo journalctl -k | grep -i memory

# Configuring systemd restart otomatis
sudo systemctl edit caddy
[Service]
Restart=on-failure
RestartSec=5s
# Jika crash lebih dari 5 kali dalam 300 detik, berhenti coba restart
StartLimitIntervalSec=300
StartLimitBurst=5

13. Sertifikat Let’s Encrypt Rate Limit #

Error: rateLimited: too many certificates already issued

Let’s Encrypt membatasi 50 sertifikat per domain per minggu.

# Gunakan staging CA untuk testing
# /etc/caddy/Caddyfile:
# {
#     acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
# }

# Atau gunakan ZeroSSL sebagai alternatif
# {
#     acme_ca https://acme.zerossl.com/v2/DV90
# }

# Cek berapa banyak sertifikat yang sudah diterbitkan
# https://crt.sh/?q=example.com
curl -s "https://crt.sh/?q=example.com&output=json" | \
    jq '[.[] | select(.not_before > (now - 604800 | todate))] | length'

14. Memory Usage Terus Meningkat #

Jika memory Caddy terus naik, kemungkinan ada memory leak atau konfigurasi yang tidak optimal:

# Monitor memory Caddy secara berkala
watch -n 30 'ps aux | grep caddy | grep -v grep | awk "{print \$6/1024 \" MB\"}"'

# Jika ada memory leak, restart terjadwal sebagai workaround sementara
# (Sambil investigasi akar masalah)
# Tambahkan di crontab:
# 0 4 * * * systemctl restart caddy  # Restart setiap jam 4 pagi

# Cek apakah plugin tertentu menyebabkan leak
# Build Caddy tanpa plugin satu per satu untuk isolasi masalah
About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact