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 :443dan 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_proxiesdengan IP load balancer.- Selalu gunakan
caddy validatesebelum 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