İçeriğe geç
KURUMSAL Kurumsal teknoloji · İşletmenize özel mühendislik Kurumsal Yazılım · Yönetilen Sunucular · Kurumsal E-posta · LiteSpeed + CloudLinux · Imunify360 Güvenlik · cPanel Yönetim · Uygun pakette 3 Gbps'ye kadar ağ profili
AIOR

Let's Encrypt SSL Yenilenmiyor: Certbot, cPanel ve DirectAdmin Çözümü

  • Konu başlatıcısı Konu başlatıcısı Aior
  • Başlangıç tarihi Başlangıç tarihi

Aior

Administrator

Yetkili üye
Katıldı
2 Nis 2023
Mesajlar
929
Tepki puanı
2
Puan
18
Yaş
41
Konum
Turkey
Web sitesi
aior.com
Konu sahibi

Let's Encrypt sertifikanız yenilenmediğinde artık sizi uyaran bir e-posta gelmiyor. Let's Encrypt, süre bitimi uyarı e-postalarını 4 Haziran 2025'te durdurdu; bu yüzden ilk işaret çoğu zaman bir ziyaretçinin ekranında beliren NET::ERR_CERT_DATE_INVALID hatası oluyor. Bu rehberde gerçekte neyin süresinin dolduğunu dışarıdan doğrulamayı, Certbot, cPanel AutoSSL ve DirectAdmin'in hata mesajlarını okumayı, en sık nedenleri (güvenlik duvarı, DNS, IPv6, yönlendirme, proxy, CAA kaydı, hız sınırları) gidermeyi ve yenilemeyi güvenilir hâle getirmeyi adım adım anlatıyoruz.

Bir de takvim meselesi var. Let's Encrypt'in 7 Ekim 2026 tarihli duyurusuna göre 10 Şubat 2027'den itibaren verilen veya yenilenen sertifikalar varsayılan olarak 90 değil 64 gün geçerli olacak; başarılı bir alan adı doğrulaması da 30 yerine 10 gün boyunca yeniden kullanılabilecek. Test ortamı (staging) 14 Ekim 2026'da 64 günlük sertifikalara geçti; 45 günlük sertifikaların ise Şubat 2028'de varsayılan olması planlanıyor. Yenileme zamanını Let's Encrypt'e soran istemcilerde (ARI, ACME Renewal Information) değişiklik gerekmiyor; sabit gün sayısına göre çalışan yenileme düzenekleri ise elden geçirilmeli.

1. Hızlı teşhis: süresi dolan ne, sertifikayı kim verdi?​

Kontrolü sunucunun dışından, ziyaretçinin gördüğü gibi yapın ve önemli her ad için (example.com, www.example.com, mail.example.com) tekrarlayın:

Bash:
# 443 portunda sunulan sertifikanın geçerlilik tarihleri, vereni ve konusu
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -dates -issuer -subject

# Kapsadığı adlar (OpenSSL 1.1.1+; LibreSSL'de -text ile "Subject Alternative Name" satırına bakın)
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -ext subjectAltName

# 14 gün (1209600 saniye) içinde doluyorsa çıkış kodu 1 olur
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -checkend 1209600

notAfter satırı bitiş zamanını UTC olarak verir. IPv4 ve IPv6 yanıtlarını ayrı ayrı görmek için s_client komutuna -4 ya da -6 ekleyin. Site bir proxy veya CDN arkasındaysa -connect SUNUCU_IP:443 -servername example.com ile doğrudan kaynak sunucuya bakın. Gördüğünüzü olası durumla eşleştirin:

GördüğünüzGenellikle anlamı
NET::ERR_CERT_DATE_INVALID (Chrome, Edge) veya SEC_ERROR_EXPIRED_CERTIFICATE (Firefox); notAfter geçmiş bir tarihYenileme başarısız oldu ya da başarılı oldu ama sunucu yeni dosyayı hiç yüklemedi
NET::ERR_CERT_COMMON_NAME_INVALID (Chrome) veya SSL_ERROR_BAD_CERT_DOMAIN (Firefox); konu (subject) sunucunun ana makine adı (hostname) ya da panelin kendinden imzalı sertifikasıAd sertifikada yok ya da istek yanlış sanal konağa (virtual host), çoğunlukla varsayılan konağa düşüyor
Veren (issuer) ve tarihler sunucudaki sertifikayla uyuşmuyor; örneğin sertifikayı CDN'inizin sertifika otoritesi vermişTLS'i önünüzdeki proxy sonlandırıyor; gördüğünüz sizin sunucunuzun değil, proxy'nin sertifikası. Cloudflare'in kenar sertifikası da Let's Encrypt imzalı olabilir; kaynak sunucuyu doğrudan kontrol edin
openssl yeni tarihleri gösteriyor ama bazı ziyaretçiler hâlâ hata alıyorTrafiğin bir kısmına başka bir adres yanıt veriyor: eski bir AAAA kaydı, ikinci bir sunucu, eski bir yük dengeleyici (load balancer)

Ardından sertifikayı kimin yönettiğini belirleyin. Bir VPS'te sudo certbot certificates komutu, Certbot'un yönettiği tüm sertifikaları adları, bitiş tarihleri ve dosya yollarıyla listeler. cPanel sunucularında bu iş genellikle AutoSSL'e, DirectAdmin'de ise panelin kendi ACME istemcisine aittir. Aynı adı iki araç yönetiyorsa (örneğin panelli bir sunucuya elle kurulmuş Certbot) biri diğerinin kurduğu sertifikayı değiştirir ya da web sunucusu kimsenin yenilemediği kopyayı sunmaya devam eder. "Yeniledim ama hâlâ süresi dolmuş görünüyor" şikâyetinin sık rastlanan bir açıklaması budur.

2. Yenileme nasıl çalışır?​

ACME istemcisi (Certbot, AutoSSL, DirectAdmin, Caddy vb.) Let's Encrypt'ten sertifika ister, her ad için bir doğrulama görevi (challenge) alır, o adı denetlediğini kanıtlar ve sertifikayı indirir. Let's Encrypt doğrulamayı birden fazla ağ konumundan yapar ve kullandığı IP adreslerini yayımlamaz; güvenlik duvarı kurallarını yazarken bunu hesaba katmak gerekir.

  • HTTP-01: İstemci, http://example.com/.well-known/acme-challenge/TOKEN biçimindeki bir adrese belirteç (token) dosyası koyar. Doğrulama her zaman 80 portundan başlar. Let's Encrypt en fazla 10 yönlendirmeyi izler; yalnızca http veya https'e, 80 ya da 443 portuna giden yönlendirmeleri kabul eder ve HTTPS hedefindeki sertifikayı denetlemez. Yani süresi dolmuş bir sertifika tek başına HTTP-01'i engellemez. Bu yöntemle joker (wildcard) sertifika alınamaz.
  • DNS-01: İstemci, _acme-challenge.example.com adına bir TXT kaydı ekler. Joker sertifikalar (*.example.com) için zorunludur; proxy arkasında ve internetten erişilemeyen sunucularda da çalışır, ancak API sunan bir DNS sağlayıcısı gerektirir.
  • TLS-ALPN-01: Doğrulama 443 portunda, TLS el sıkışmasının içinde yapılır; Caddy gibi bazı sunucu ve proxy'ler kullanır. Certbot eklentileri HTTP-01 veya DNS-01 kullanır.

Başarılı bir doğrulamanın ardından Let's Encrypt bu yetkilendirmeyi (authorization) hesabınız için önbellekte tutar: bugün en fazla 30 gün, 10 Şubat 2027'den itibaren 10 gün. Bu süre içinde yeniden alınan bir sertifika hiç doğrulama yapılmadan verilebilir; dolayısıyla elle tekrar çalıştırıp "oldu" demek pek bir şey kanıtlamaz. Certbot'un deneme çalıştırması (dry run) her seferinde test ortamından taze yetkilendirme istediği için daha güvenilir bir testtir.

Certbot'un durumunu ve zamanlamasını şu komutlarla görebilirsiniz:

Bash:
sudo certbot certificates                  # her sertifikanın adları, bitiş tarihi ve yolları
ls /etc/letsencrypt/renewal/               # sertifika başına bir .conf: authenticator, webroot, kancalar
systemctl list-timers | grep -i certbot    # yenileme zamanlayıcısı etkin mi?
sudo certbot renew --dry-run               # test ortamına karşı tam deneme; sertifikalar değiştirilmez
sudo certbot renew --cert-name example.com --dry-run   # tek bir sertifikayı dene
sudo less /var/log/letsencrypt/letsencrypt.log         # son çalıştırmanın ayrıntılı günlüğü

Certbot nasıl kuruldu?ZamanlayıcıDikkat
snapsnap.certbot.renew.timer, günde yaklaşık iki kezGüncel sürüm, ARI desteği dahil
Debian ve Ubuntu'da aptcertbot.timer; systemd olmayan sistemler için /etc/cron.d/certbotEski sürümler: Debian 12'de 2.1.0, Ubuntu 24.04'te 2.9.0
Fedora veya EPEL'den dnf (AlmaLinux, Rocky Linux)certbot-renew.timerKurulumla birlikte başlamaz: systemctl enable --now certbot-renew.timer
pip veya elle kurulumNe kurduysanız oÇoğu zaman hiçbir şey; crontab -l çıktısına ve /etc/cron.d/ dizinine bakın

--manual ile alınan sertifikalar, bir kimlik doğrulama kancası (auth hook) betiği vermediğiniz sürece kendiliğinden yenilenmez.

3. Hata, neden, çözüm​

Certbot, sertifika otoritesinin kararını "Certbot failed to authenticate some domains" başlığı altında, her ad için ayrı bir blok hâlinde yazar:

Kod:
Certbot failed to authenticate some domains (authenticator: webroot). The Certificate Authority reported these problems:
  Domain: www.example.com
  Type:   unauthorized
  Detail: 2001:db8::10: Invalid response from http://www.example.com/.well-known/acme-challenge/x8Kq...: 404

Hint: The Certificate Authority failed to download the temporary challenge files created by Certbot. ...

Certbot 5.3.0 ve sonrası Domain yerine Identifier yazar. Detail satırının başındaki adres, hata anında Let's Encrypt'in bağlandığı IP adresidir; orada bir IPv6 adresi görüyorsanız sorun büyük olasılıkla IPv6 tarafındadır (4. bölüm). Doğrulamayı Let's Encrypt'in kendisi reddettiğinde cPanel ve DirectAdmin günlüklerinde de aynı metinleri görürsünüz.

Hata (Detail)Olağan nedenÇözüm
Timeout during connect (likely firewall problem)80 portuna internetten ulaşılamıyor: bulut güvenlik duvarı veya güvenlik grubu, ufw/firewalld, ülke engelleme ya da eski bir IP'yi gösteren DNSTCP 80'i tüm kaynaklara açın; A kaydını kontrol edin; 4. bölüme bakın
Connection refused80 portunu dinleyen bir şey yok: web sunucusu yalnızca 443'te, konteyner portu dışarı açılmamış, standalone çalışmıyor80 portuna bir dinleyici ekleyin; bu dinleyici doğrulama yolu dışındaki her şeyi HTTPS'e yönlendirebilir
Invalid response from http://…/.well-known/acme-challenge/…: 404Yanlış webroot, taşınmış belge kök dizini (document root), yolu uygulamanın ya da bir rewrite kuralının yakalaması, yönlendirilen HTTPS sitesinin başka bir dizinden sunulması, başka bir sunucunun yanıt vermesiBir test dosyasıyla deneyin (5. bölüm); yolu rewrite kurallarının dışında tutun
Aynısı, 403 ileGizli yolları engelleyen bir kural, dosya izinleri, SELinux etiketi, WAF ya da bot koruması/.well-known/acme-challenge/ yoluna açıkça izin verin; izinleri ve etiketleri kontrol edin
The key authorization file from the server did not match this challenge200 döndüren başka bir sunucu ya da sanal konak: eski IP, eski AAAA kaydı, her şeyi yakalayan varsayılan konak, önbellekleyen bir proxycurl -4 ve curl -6 sonuçlarını karşılaştırın; DNS'i ya da sanal konağı düzeltin
invalid host in redirect target "example.com.well-known"Sonunda eğik çizgi olmayan bir yönlendirme (Redirect / https://example.com)Eğik çizgiyi ekleyin ya da doğrulama yolunu hariç tutun
redirect loop detected; Received disallowed redirect status code 303Çakışan yönlendirme kuralları; Let's Encrypt yalnızca 301, 302, 307 ve 308 yönlendirmelerini izlerTek bir 301 yönlendirmesi kullanın ya da doğrulama yolunu hariç tutun
DNS problem: NXDOMAIN looking up A for www.example.com - check that a DNS record exists for this domainAdın kaydı yok: silinmiş alt alan adı, eksik www, yazım hatası, süresi dolmuş alan adı ya da yönlendirilmiş alan adı (domain pointer)Kaydı ekleyin ya da adı sertifikadan çıkarın
DNS problem: SERVFAIL looking up CAA for example.com - the domain's nameservers may be malfunctioning (ya da "DNSSEC: Bogus")Çoğunlukla bozuk DNSSEC (örneğin DNS sağlayıcısı değiştikten sonra kayıt firmasında, yani registrar'da kalan eski DS kaydı); CAA sorgularını yanlış işleyen ad sunucusu; ad sunucusu kesintisidnsviz.net ile kontrol edin; DS kaydını düzeltin ya da kaldırın; DNS sağlayıcısına başvurun
CAA record for example.com prevents issuanceCAA kaydı yalnızca başka bir sertifika otoritesine izin veriyor0 issue "letsencrypt.org" ekleyin; bir issuewild kaydı varsa joker sertifikalar için ona da letsencrypt.org ekleyin
too many certificates (5) already issued for this exact set of identifiers in the last 168h0m0s, retry after …Aynı ad kümesi için tekrar tekrar sertifika alınması, çoğunlukla sorun giderirkenDurun, test ortamında deneyin, verilen zamanı bekleyin
too many failed authorizations (5) for "example.com" in the last 1h0m0s, retry after …Bir saat içinde beş başarısız doğrulamaÖnce nedeni düzeltin; her 12 dakikada bir deneme hakkı geri gelir
Your account is temporarily prevented from requesting certificates for example.com and possibly others. Please visit: …Uzun süre art arda başarısız olunduğu için bu ad için sertifika verilmesi duraklatıldıNedeni düzeltin, sonra bağlantıyı açıp duraklatmayı kaldırın
Could not bind TCP port 80 because it is already in use (Certbot, yerel)Web sunucusu 80 portunu tutarken standalone doğrulayıcının kullanılmasıwebroot, nginx ya da apache'ye geçin (6. bölüm)

Hız sınırları elle sıfırlanamaz; sertifikaları iptal etmek (revoke) de onları sıfırlamaz. Sorun giderirken --dry-run veya --staging kullanın, çünkü test ortamının sınırları çok daha yüksektir.

4. Güvenlik duvarı, IPv6 ve proxy​

80 portu herkese açık olmalı​

Let's Encrypt birden fazla konumdan doğruladığı ve adreslerini yayımlamadığı için onu izin listesine (allow list) ekleyemezsiniz. 80 portunu yalnızca Türkiye'ye ya da birkaç ülkeye açan kurallar (bulut güvenlik duvarındaki ülke engelleme ya da CSF'nin ülke seçenekleri gibi), site sizin tarayıcınızda sorunsuz açılsa bile HTTP-01'i bozar. TCP 80'i tüm kaynaklara açık tutun ve ziyaretçileri oradan HTTPS'e yönlendirin; kurum politikası buna izin vermiyorsa DNS-01 kullanın. Her katmanı ayrı ayrı kontrol edin: sağlayıcının ağ güvenlik duvarı veya güvenlik grubu (security group), sunucudaki güvenlik duvarı (ufw, firewalld, nftables) ve arada duran cihazlar.

IPv6: en çok gözden kaçan neden​

Bir adın AAAA kaydı varsa Let's Encrypt önce IPv6'yı dener. IPv4'e yalnızca IPv6 bağlantısı hiç kurulamadığında (bağlantı reddedildiğinde, adrese ulaşılamadığında ya da bağlanırken zaman aşımı olduğunda) geçer. IPv6 adresi bağlantıyı kabul edip yanlış yanıt verirse (404, başka bir site, eski sunucu ya da bağlantıdan sonra gelen bir hata) IPv4 hiç denenmeden doğrulama başarısız olur. Tipik senaryolar: taşımadan sonra AAAA kaydı hâlâ eski sunucuyu gösteriyor; web sunucusu IPv6'yı yalnızca varsayılan sanal konakta dinliyor ve sitenize gelen IPv6 istekleri oraya düşüyor; sağlayıcı IPv6 trafiğini başka bir makineye yönlendiriyor. İki yolu ayrı ayrı test edin:

Bash:
dig +short A example.com
dig +short AAAA example.com
# test.txt dosyasını 5. bölümdeki gibi oluşturduktan sonra; çıktı: durum kodu ve yanıt veren IP
curl -4 -sSLk -o /dev/null -w "%{http_code} %{remote_ip}\n" http://example.com/.well-known/acme-challenge/test.txt
curl -6 -sSLk -o /dev/null -w "%{http_code} %{remote_ip}\n" http://example.com/.well-known/acme-challenge/test.txt

Siteyi IPv6 üzerinden sunmuyorsanız yarım çalışan bir AAAA kaydı bırakmak yerine onu silin. AAAA ve CAA kayıtlarını DNS kayıtları rehberimizde daha ayrıntılı anlattık.

Önde Cloudflare veya başka bir proxy varsa​

Proxy açıkken (Cloudflare'deki turuncu bulut) Let's Encrypt'in isteği önce proxy'ye gelir, proxy de onu sunucunuza iletir. /.well-known/acme-challenge/ yolu olduğu gibi geçtiği sürece HTTP-01 çalışmaya devam eder; bir WAF kuralı, bot koruması ya da sayfa kuralı sunucunuzun yerine yanıt verdiğinde bozulur. Bir tuzak daha var: kenar sunucudaki (edge) Always Use HTTPS yönlendirmesi doğrulama isteğini HTTPS'e çevirir. Proxy kaynak sunucunun (origin) sertifikasını sıkı biçimde denetliyorsa, örneğin Cloudflare Full (strict) modundaysa, süresi dolmuş kaynak sertifikası 526 hatasına yol açar ve belirteç hiç okunamaz. Seçenekleriniz:

  • Doğrulama yolunu güvenlik kurallarından ve kenar yönlendirmelerinden muaf tutun.
  • Yenileme sırasında kaydı yalnızca DNS (gri bulut) moduna alın, ardından proxy'yi yeniden açın.
  • DNS sağlayıcınızın API'si üzerinden DNS-01 kullanın (10. bölüm). Proxy arkasında en sağlam yol budur; joker sertifikalar için de tek yoldur.

5. Doğrulama yolunda 404 ve 403 hatalarını düzeltmek​

Kontrolü, istemcinin kullandığı web kök dizinine (/etc/letsencrypt/renewal/example.com.conf içindeki webroot_path) bir test dosyası koyarak kendiniz tekrarlayın. Örnekteki dizin, aşağıda Certbot'a tanıtacağımız /var/www/letsencrypt; sizinki farklıysa yolu değiştirin:

Bash:
sudo mkdir -p /var/www/letsencrypt/.well-known/acme-challenge
echo ok | sudo tee /var/www/letsencrypt/.well-known/acme-challenge/test.txt
curl -4 -iLk http://example.com/.well-known/acme-challenge/test.txt
curl -6 -iLk http://example.com/.well-known/acme-challenge/test.txt

Hem IPv4 hem IPv6 üzerinden, gövdesinde ok yazan bir 200 yanıtı almalısınız. -L yönlendirmeleri izler, -k ise Let's Encrypt gibi sertifika hatalarını yok sayar; yönlendirmeler sorun değildir, yeter ki sonunda bu dosyaya varsın. /var/www/letsencrypt gibi ayrı bir dizin, yolu uygulamadan bağımsız tutar; SELinux kullanan RHEL ailesi sistemlerde de web sunucusunun okuyabileceği etiketi devralır.

Nginx'te bu yolu, herhangi bir yönlendirmeden önce, 80 portundaki server bloğunda bu dizinden sunun. ^~ öneki, gizli dosyaları engelleyen kural gibi düzenli ifadeli (regex) location bloklarının isteği yakalamasını önler:

Kod:
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/letsencrypt;
        default_type "text/plain";
        try_files $uri =404;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

Sunucu bloğunun doğrudan içinde duran bir return 301 satırı, location blokları seçilmeden önce çalışır ve doğrulama yolunu da yönlendirir; yönlendirmeyi örnekteki gibi location / içine taşıyın. Sonra Certbot'u bir kez bu dizine yönlendirin: sudo certbot reconfigure --cert-name example.com --webroot -w /var/www/letsencrypt

Apache'de yolu HTTPS yönlendirmesinden önce hariç tutun:

Kod:
Alias /.well-known/acme-challenge/ /var/www/letsencrypt/.well-known/acme-challenge/
<Directory "/var/www/letsencrypt/.well-known/acme-challenge/">
    Require all granted
</Directory>

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Laravel veya WordPress gibi uygulamaların kendi 404 sayfasını görüyorsanız, belirteç büyük olasılıkla sitenin sunduğundan farklı bir dizine yazılıyordur (Laravel örneğin public/ dizinini sunar); bu durumda isteğe uygulamanın ön denetleyicisi (front controller) yanıt verir. "current" sembolik bağını değiştirerek dağıtım yapılan sistemlerde webroot'un eski bir sürüm dizinini göstermesi de sık görülür. Konteynerlerde ACME istemcisi ile web sunucusu aynı doğrulama dizinini bir birim (volume) üzerinden paylaşmalıdır. 403 alıyorsanız location ~ /\. { deny all; } gibi kuralları, dizin izinlerini, özel dizinlerdeki SELinux etiketlerini ve ModSecurity gibi WAF kurallarını kontrol edin.

6. Certbot'ta kalıcı çözümler​

Doğru doğrulayıcıyı (authenticator) seçin​

grep -H authenticator /etc/letsencrypt/renewal/*.conf komutuyla bakın. standalone, Certbot'un 80 portunu kendisinin açması demektir; Nginx ya da Apache çalışırken "Could not bind TCP port 80" hatasıyla düşer. certbot reconfigure ile webroot, nginx veya apache'ye geçin. Bu komut Certbot 2.3.0'dan beri vardır; önce test ortamında bir deneme yapar ve değişikliği yalnızca deneme başarılı olursa kaydeder. Debian 12'deki 2.1.0 sürümünde bu komut yoktur: orada Certbot belgelerinde anlatıldığı gibi certbot renew --cert-name example.com komutunu yeni seçeneklerle ve --dry-run ile çalıştırın, başarılı olursa bir kez de --force-renewal ile çalıştırın.

Artık var olmayan adları çıkarın​

Artık çözümlenmeyen tek bir ad bile bütün yenilemeyi başarısız kılar. Aynı sertifikayı yalnızca tuttuğunuz adlarla yeniden alın: sudo certbot certonly --cert-name example.com -d example.com -d www.example.com (kullandığınız doğrulayıcı seçenekleriyle birlikte).

Çift sertifikaları temizleyin​

example.com ile example.com-0001'in yan yana durması genellikle sonraki bir çalıştırmanın ikinci bir sertifika oluşturduğunu gösterir. Web sunucunuzun hangi yolu yüklediğine bakın (grep -R "letsencrypt/live" /etc/nginx /etc/apache2 /etc/httpd 2>/dev/null), kullanılmayanı sudo certbot delete --cert-name example.com-0001 gibi bir komutla silin.

Yenilemeden sonra servisleri yeniden yükleyin​

nginx ve apache eklentileri sunucuyu sizin yerinize yeniden yükler (reload); webroot ve standalone yüklemez. Bu durumda yeni dosya diskte bekler, bellekteki eski sertifika sunulmaya devam eder. Yalnızca başarılı bir yenilemeden sonra çalışan bir dağıtım kancası (deploy hook) ekleyin: aşağıdaki betiği /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh olarak kaydedin (sudoedit işinizi görür) ve sudo chmod 755 ile çalıştırılabilir yapın.

Bash:
#!/bin/sh
# /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
# Yalnızca başarılı yenilemeden sonra çalışır; $RENEWED_LINEAGE live/ dizinini gösterir
systemctl reload nginx
# systemctl reload postfix dovecot   # e-posta servisleri aynı sertifikayı kullanıyorsa

Zamanlayıcı ve sürüm​

systemctl list-timers çıktısında Certbot zamanlayıcısı yoksa paketinizin getirdiğini etkinleştirin (2. bölümdeki tablo) ve günlüğünü journalctl -u certbot.service ile okuyun (Fedora ve EPEL'de certbot-renew.service, snap kurulumunda snap.certbot.renew.service). Aynı makinede hem snap hem de apt veya dnf ile kurulmuş Certbot varsa, elle çalıştırdığınız komutla zamanlayıcının çalıştırdığı farklı olabilir; Certbot'un snap kurulum talimatı da önce paket yöneticisindeki Certbot'u kaldırmayı söyler. Yenileme dosyası nginx ya da apache eklentisini gösteriyor ama eklenti kurulu değilse yenileme "The requested nginx plugin does not appear to be installed" hatasıyla durur; python3-certbot-nginx ya da python3-certbot-apache paketini kurun. Son olarak certbot --version ile sürüme bakın:

Certbot sürümüNe zaman yeniler?Hangi dağıtımda (bu yazı hazırlanırken)
4.0.0 öncesiBitişe 30 gün kala; renew_before_expiry başka bir değer vermiyorsaDebian 12 (2.1.0), Ubuntu 24.04 (2.9.0), EPEL 9 (3.1.0)
4.0.xÖmrün üçte biri kaldığında (ömrü 10 gün veya daha kısa sertifikalarda yarısı)Debian 13 ve Ubuntu 26.04 (4.0.0)
4.1.0 ve sonrasıLet's Encrypt ARI ile ne zaman önerirse; genellikle ömrün yaklaşık üçte ikisindeEPEL 10 (4.2.0), snap ve pip (5.x)

Üç davranış da 64 günlük sertifikalarla çalışır. Eski sürümlerin eksiği ARI'dir: Let's Encrypt sertifikaları iptal etmek zorunda kaldığında erken yenileme yapamazlar ve yenilemeleri ARI'nin hız sınırı muafiyetinden yararlanamaz. Yenileme dosyalarında elle yazılmış bir renew_before_expiry değeri de arayın; birkaç gün gibi küçük bir değer yeniden denemelere zaman bırakmaz.

7. cPanel AutoSSL​

Güncel cPanel & WHM'de yeni kurulumların varsayılan AutoSSL sağlayıcısı Let's Encrypt'tir; hangi sağlayıcının seçili olduğunu Manage AutoSSL'deki Providers sekmesinde görürsünüz. AutoSSL tüm kullanıcılar için gece güncellemesi sırasında ve günlük bir cron işiyle çalışır; Let's Encrypt sertifikalarını bitişlerine 29 gün kala yenilemeye çalışır. Sertifikaya yalnızca alan adı doğrulamasından (DCV, domain control validation) geçen adları ekler: tek bir sorunlu ad diğerlerini engellemez ama o ad korumasız kalır. Hız sınırları yüzünden yeni sertifikaları yenilemelerin önüne koyar.

  • Günlükler: WHM » Home » SSL/TLS » Manage AutoSSL, Logs sekmesi. Dosyalar /var/cpanel/logs/autossl/ altında metin ve JSON olarak durur ve 30 gün saklanır.
  • Elle çalıştırma: cPanel'de Security » SSL/TLS Status » Run AutoSSL. "Has AutoSSL Problems" filtresi sorunlu alan adlarını, durum sütunu da günlüğe düşen hatayı gösterir. root olarak: /usr/local/cpanel/bin/autossl_check --user=kullaniciadi (ya da --all). Sunucunun ana makine adı için cPanel'in SSL rehberi /usr/local/cpanel/bin/checkallsslcerts betiğini gösterir; betiğin kendi sayfası ise onu yalnızca cPanel desteği önerdiğinde çalıştırmanızı tavsiye ediyor.
  • Alan adı başka yeri gösteriyor: DNS'i başka bir sağlayıcıda duran ve hâlâ eski sunucuyu gösteren kayıtlar, başka bir makineye ait AAAA kaydı ya da önde duran bir proxy. HTTP ile yapılan DCV'nin geçmesi için isteğin bu sunucuya ulaşması gerekir.
  • Rewrite kuralları: /.well-known/ isteklerini uygulamaya ya da başka bir alan adına gönderen .htaccess kuralları.
  • Servis alt alan adları: DNS kaydı olmayan cpanel., webmail., webdisk. ve autodiscover. adları DCV'den geçemez ve atlanır; ihtiyacınız varsa kayıtlarını ekleyin (/usr/local/cpanel/scripts/servicedomains betiği bu kayıtları oluşturabilir).
  • Diğer durumlar: askıya alınmış (suspended) hesaplara sertifika verilmez; CAA kaydı letsencrypt.org'a izin vermelidir (AutoSSL bu kaydı yalnızca sunucuda barındırılan bölgelere kendisi ekleyebilir); joker sertifikalar için DNS'in sunucuda ya da sunucunun DNS kümesinde (DNS cluster) barındırılması gerekir.

8. DirectAdmin​

Güncel DirectAdmin sürümleri, sertifikaları 24 saatte bir kontrol eden ve arka planda lego kullanan yerleşik bir ACME istemcisiyle gelir. Varsayılan ayarda sertifika, ömrünün %65'i dolduğunda yenilenir (acme_cert_lifetime_renew_threshold=0.65, en fazla ±%5 rastgele sapmayla); bu davranış 64 günlük sertifikalara da uyar. Yenileme "kendiliğinden durduysa" önce iki ayara bakın: acme_disable_after_failures=5, beş başarısız denemeden sonra o sertifikanın otomatik alınmasını ve yenilenmesini kapatır; bu yüzden nedeni düzelttikten sonra beklemeyin, sertifikayı kendiniz yeniden isteyin. Kullanıcılar da başarısız yenilemelerden yalnızca letsencrypt_renewal_error_to_users ayarı varsayılan değeri olan 1'de kaldığı sürece haberdar olur.

  • Nereye bakılır: Yeniden istemek için User Level » SSL Certificates (ACME ayarları); tüm alan adlarına toplu bakış için Admin Level » Admin SSL; ana makine adı için Server Manager » Server TLS Certificate. Ana makine sertifikası /usr/local/directadmin/scripts/letsencrypt.sh server_cert komutuyla da yenilenebilir.
  • Alan adı başına günlük: /usr/local/directadmin/data/users/KULLANICI/domains/acme_provider_cert_logs/ALANADI.log. Günlük yoksa ya da içindeki tarihler eskiyse DirectAdmin büyük olasılıkla hiç denememiştir.
  • Doğrulama yolu: echo test > /var/www/html/.well-known/acme-challenge/test.txt, ardından curl -I -L -k -X GET http://ALANADI/.well-known/acme-challenge/test.txt. /.well-known takma adı (alias) eksikse da build rewrite_confs onu ekler; da build letsencrypt istemciyi günceller.

Taşıma, bu sorunları sık tetikleyen durumlardan biridir. Taşımadan sonra cPanel'den DirectAdmin'e taşıma rehberimizdeki DNS adımına ikinci kez bakın: A ve AAAA kayıtları yeni sunucuyu göstermeli, eski kurulumdan taşınan bir CAA kaydı yalnızca başka bir sertifika otoritesine izin veriyor olabilir ve DNS'i artık çalışmayan bir yönlendirilmiş alan adı (domain pointer), sertifika isteğinin tamamını SERVFAIL hatasıyla düşürebilir. Joker sertifikalar için dns_ttl=1 ayarının yanında ya yerel bir DNS bölgesi ya da User Level » SSL Certificates » Manage ACME DNS Providers altında tanımlanmış bir sağlayıcı gerekir.

9. 64 günlük sertifikalar gelmeden yenilemeyi sağlamlaştırın​

  • ARI destekli bir istemci kullanın: Certbot 4.1.0 ve sonrası, lego ve Caddy (CertMagic) ARI'yi (RFC 9773) destekler. Let's Encrypt'in entegrasyon rehberi ARI'nin günde en az iki kez sorgulanmasını öneriyor; ARI ile yapılan yenilemeler tüm hız sınırlarından muaftır.
  • Sabit gün sayılarını kaldırın: Let's Encrypt, cron işlerinde, sarmalayıcı betiklerde ve çalışma kılavuzlarında (runbook) 60, 80, 83 gibi değerleri aramayı ve bunların yerine ömrün yaklaşık üçte ikisinde yenilemeyi öneriyor.
  • Sertifika alındıktan sonraki her adımı otomatikleştirin: servislerin yeniden yüklenmesi; yük dengeleyicilere, e-posta sunucularına, donanım cihazlarına ve Java keystore'lara kopyalama. 64 günlük sertifikalarla elle yapılan her adım daha sık karşınıza çıkar.
  • Dışarıdan izleyin: Let's Encrypt artık e-posta göndermiyor. Sitesindeki Monitoring Service Options sayfası Red Sift Certificates Lite (250 sertifikaya kadar ücretsiz) gibi servisleri listeliyor; kendi altyapınızda bir cron betiği ya da Prometheus blackbox_exporter'ın probe_ssl_earliest_cert_expiry metriği de iş görür.
  • Yalnızca süre dolumunda değil, başarısızlıkta da uyarı alın: certbot renew bir yenileme başarısız olduğunda 1 çıkış koduyla biter, bu yüzden zamanlayıcının servisi failed durumuna düşer (systemctl is-failed certbot.service; servis adı kurulumunuza göre değişir). Başarısız adları post kancalarına FAILED_DOMAINS değişkeniyle ileten ilk sürüm 4.2.0'dır; 2.7.0'da belgelenen bu değişken, o sürüme kadar başarısızlık durumunda boş kalıyordu.
  • Birden fazla sunucu: /.well-known/acme-challenge/ yolunu tüm düğümlerden istemcinin çalıştığı düğüme yönlendirin ya da sertifikayı DNS-01 ile tek yerde alıp dosyaları bir dağıtım kancasıyla dağıtın. Her düğüm aynı ad kümesini ayrı ayrı isterse haftada 5 sertifikalık sınırı paylaşırlar.

Bash:
# Sabit yenileme aralıklarını bulun (bazı yanlış eşleşmeler çıkabilir)
sudo grep -RnE -- '--days|renew_before_expiry|force-renew|(^|[^0-9])(60|80|83)([^0-9]|$)' \
  /etc/cron* /var/spool/cron /etc/systemd/system /etc/letsencrypt/renewal /usr/local/bin 2>/dev/null

# Günlük dış kontrol: başka bir makinede cron ile çalıştırın; o makine e-posta
# gönderebiliyorsa cron her çıktıyı MAILTO adresine (ya da iş sahibine) iletir
for host in example.com www.example.com; do
  echo | openssl s_client -connect "$host:443" -servername "$host" 2>/dev/null \
    | openssl x509 -noout -checkend 864000 >/dev/null \
    || echo "$host: sertifika 10 gün içinde doluyor ya da okunamadı"
done

Başarısız yenilemeleri sistem günlüğüne yazan bir post kancası (Certbot 4.2.0+); dağıtım kancası gibi bunu da çalıştırılabilir yapın:

Bash:
#!/bin/sh
# /etc/letsencrypt/renewal-hooks/post/alert-on-failure.sh
[ -n "$FAILED_DOMAINS" ] && logger -t certbot "yenileme başarısız: $FAILED_DOMAINS"
exit 0

E-posta sunucuları için aynı komutla 993 portunu ya da -starttls smtp ile 587 portunu kontrol edin. Uyarı eşiklerini yeni ömürlere göre ayarlayın: 30 gün kala uyaran bir izleme, sağlıklı her 64 günlük sertifika için de alarm üretir ve bir süre sonra kimse bu alarmları ciddiye almaz. Aşağıdaki eşikler öneri niteliğindedir:

Sertifika ömrüYaklaşık üçte ikide yenilemeYenilemede kalan günUyarı eşiği
90 gün (10 Şubat 2027'ye kadar)60. günYaklaşık 3015 günün altı
64 gün (10 Şubat 2027'den itibaren varsayılan)42. veya 43. günYaklaşık 2110 günün altı
45 gün (Şubat 2028'den itibaren planlanan varsayılan)30. günYaklaşık 157 günün altı

10. DNS-01 ve yetkisi kısıtlı API token'ıyla joker sertifika​

Joker sertifikalar DNS-01 gerektirir; bu yüzden API'si sağlam bir DNS sağlayıcısı seçin. Cloudflare, Route 53, BunnyDNS ve NS1'i yönetilen DNS servisleri karşılaştırmamızda ele aldık. Cloudflare kullanıyorsanız Global API Key yerine yalnızca ihtiyaç duyduğunuz bölgeler için Zone:DNS:Edit yetkisi taşıyan bir API token'ı oluşturun ve certbot-dns-cloudflare eklentisini kurun (snap eklentisi ya da Debian ve Ubuntu'da python3-certbot-dns-cloudflare paketi). Kimlik bilgisi dosyasında tek bir ayar yeterlidir:

INI:
# /root/.secrets/certbot/cloudflare.ini
dns_cloudflare_api_token = YALNIZCA_ZONE_DNS_EDIT_YETKILI_TOKEN

Bash:
# Eklenti: snap kurulumunda ilk iki satır, Debian/Ubuntu paketinde üçüncü satır
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare
# sudo apt install python3-certbot-dns-cloudflare

sudo install -d -m 700 /root/.secrets/certbot
sudoedit /root/.secrets/certbot/cloudflare.ini        # yukarıdaki satırı yapıştırın
sudo chmod 600 /root/.secrets/certbot/cloudflare.ini

sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/certbot/cloudflare.ini \
  --dns-cloudflare-propagation-seconds 60 \
  -d example.com -d '*.example.com'

Web sunucusunda duran bir token, yetkili olduğu bölgelerdeki DNS kayıtlarını yine de değiştirebilir. Bu riski daraltmak için _acme-challenge.example.com adını, yalnızca doğrulama için kullanılan ayrı bir bölgedeki bir kayda CNAME ile yönlendirebilirsiniz: Let's Encrypt, DNS-01'de CNAME ve NS ile yapılan yetki devrini izler. İstemcinizin de bu düzeni desteklemesi gerekir; certbot-dns-cloudflare gibi Certbot DNS eklentileri kaydı doğrudan alan adının kendi bölgesine yazar, acme-dns ise tam bu iş için yazılmış küçük bir DNS sunucusudur. Diğer yol, DNS-01'i ayrı bir makinede çalıştırıp sertifikaları web sunucularına kopyalamaktır. Eski _acme-challenge TXT kayıtlarını silin; yanıt fazla büyürse Let's Encrypt onu reddeder. Let's Encrypt ayrıca, _validation-persist.example.com adına bir kez eklenen TXT kaydının ACME hesabınıza kalıcı yetki verdiği DNS-PERSIST-01 yöntemini duyurdu; buna göre plan yapmadan önce yöntemin güncel durumunu ve istemcinizin desteğini kontrol edin.

Kontrol listesi​

  • Dışarıdan çalıştırılan openssl, her ana makine adı için IPv4 ve IPv6 üzerinden beklenen vereni, adları ve tarihleri gösteriyor.
  • Her sertifikayı tek bir araç yönetiyor.
  • TCP 80 tüm internete açık ya da sertifika DNS-01 ile alınıyor.
  • Her AAAA kaydı aynı siteyi sunan bir sunucuyu gösteriyor.
  • Sertifikadaki her ad için /.well-known/acme-challenge/ altındaki test dosyası 200 döndürüyor.
  • Hiçbir CAA kaydı letsencrypt.org'u dışlamıyor ve DNSSEC doğrulaması geçiyor (dnsviz.net).
  • Sertifikada yalnızca hâlâ çözümlenen adlar var.
  • sudo certbot renew --dry-run ya da panelin elle çalıştırması başarılı.
  • Bir zamanlayıcı veya cron işi var ve yakın zamanda çalışmış.
  • Bir dağıtım kancası, sertifikayı kullanan her servisi yeniden yüklüyor.
  • Hiçbir iş, betik veya kılavuz sabit gün sayısına göre yenileme yapmıyor.
  • Eşikleri 64 günlük sertifikalara uygun bir dış izleme ve başarısız yenileme için ayrı bir uyarı var.

Sık sorulan sorular​

Sertifikanın süresi çoktan doldu. En hızlı güvenli çözüm ne?
sudo certbot renew --dry-run komutunu ya da panelin AutoSSL veya ACME kontrolünü çalıştırın ve bildirdiği hatayı düzeltin. Ardından sudo certbot renew komutunu bir kez çalıştırın; dağıtım kancanız yoksa web sunucusunu yeniden yükleyin. --force-renewal'ı art arda denemeyin: başarısız doğrulamalar saatlik sınıra, tekrar tekrar alınan sertifikalar haftalık sınıra sayılır.

Sunucumda hiçbir şey değişmedi, yenileme neden durdu?
Genellikle çevresinde bir şey değişmiştir: DNS, yeni bir AAAA kaydı, bir güvenlik duvarı ya da proxy kuralı, silinmiş ama sertifikada hâlâ duran bir alt alan adı, kapatılmış bir zamanlayıcı ya da DirectAdmin'de art arda hatalardan sonra kapanan otomatik yenileme.

64 günlük sertifikalar için bir şey değiştirmem gerekiyor mu?
İstemciniz ARI kullanıyor ya da ömrün yaklaşık üçte ikisinde yeniliyorsa hayır. Sabit aralıkları arayın, izleme eşiklerini güncelleyin ve bir deneme çalıştırması yapın; test ortamı 14 Ekim 2026'dan beri 64 günlük sertifika veriyor.

Site Cloudflare arkasındayken yenileme yapabilir miyim?
Evet. Doğrulama yolu sunucunuza değişmeden ulaşıyorsa HTTP-01 çalışır; ulaşmıyorsa yetkisi kısıtlı bir API token'ıyla DNS-01'e geçin. Joker sertifikalar her zaman DNS-01 gerektirir.

Hız sınırına takıldım. Sıfırlanabilir mi?
Hayır; sertifikaları iptal etmek de sıfırlamaz. Nedeni düzeltin, test ortamında deneyin ve hata mesajındaki zamanı bekleyin. Aynı ad kümesi için haftada 5 sertifika sınırında her 34 saatte bir hak geri gelir.

Sonuç ve sonraki adımlar​

Yenileme hataları kısa bir listeye iner: kapalı 80 portu, başka yeri gösteren DNS ya da IPv6, doğrulama yolunu yakalayan rewrite ve proxy kuralları, CAA veya DNSSEC hataları ve yeni dosyayı hiç yüklemeyen sunucular. Bugün yapılacaklar: her sunucuda bir deneme çalıştırması yapın, IPv4 ve IPv6 yanıtlarını karşılaştırın ve dış izleme kurun. 10 Şubat 2027'den önce yapılacaklar: sabit aralıklı yenileme işlerini kaldırın, ARI destekli bir istemciye geçin ve her yeniden yükleme ile kopyalama adımını otomatikleştirin. Kurum doğrulamalı (OV) bir sertifikaya ihtiyacınız varsa ya da kurulumun hizmet olarak yapılmasını tercih ediyorsanız AIOR'un SSL sertifikası hizmeti seçeneklerden biri. Hâlâ takıldıysanız Detail satırının tamamını ve kurulumunuzu kısaca bu konuya yazın.

When a Let's Encrypt certificate stops renewing, nothing warns you any more. Let's Encrypt ended its expiry reminder emails on 4 June 2025, so the first sign is often a visitor reporting NET::ERR_CERT_DATE_INVALID. This guide shows how to confirm what has actually expired, read the exact error from Certbot, cPanel AutoSSL or DirectAdmin, fix the usual causes (firewall, DNS, IPv6, redirects, proxies, CAA records, rate limits) and make renewal dependable.

There is also a deadline. In its announcement of 7 October 2026, Let's Encrypt said that certificates issued or renewed on or after 10 February 2027 will be valid for 64 days by default instead of 90, and that a successful domain validation can then be reused for 10 days instead of 30. The staging environment switched to 64-day certificates on 14 October 2026, and 45-day certificates are planned to become the default in February 2028. Clients that ask Let's Encrypt when to renew (ARI, ACME Renewal Information) need no changes. Renewal jobs built on fixed day counts do.

1. Quick triage: what has expired, and who issued it?​

Check from outside the server, the way visitors see it, and repeat for every name that matters (example.com, www.example.com, mail.example.com):

Bash:
# Validity dates, issuer and subject of the certificate served on port 443
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -dates -issuer -subject

# Names it covers (OpenSSL 1.1.1+; with LibreSSL use -text and find "Subject Alternative Name")
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -ext subjectAltName

# Exit code 1 if it expires within 14 days (1209600 seconds)
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -checkend 1209600

The notAfter line is the expiry time in UTC. Add -4 or -6 to s_client to see the IPv4 and IPv6 answers separately. If the site sits behind a proxy or CDN, use -connect SERVER_IP:443 -servername example.com to look at the origin server directly. Match what you see to the likely situation:

What you seeWhat it usually means
NET::ERR_CERT_DATE_INVALID (Chrome, Edge) or SEC_ERROR_EXPIRED_CERTIFICATE (Firefox); notAfter is in the pastRenewal failed, or it worked and the server never loaded the new file
NET::ERR_CERT_COMMON_NAME_INVALID (Chrome) or SSL_ERROR_BAD_CERT_DOMAIN (Firefox); the subject is the server hostname or a self-signed panel certificateThe name is not in the certificate, or the request reaches the wrong (often the default) virtual host
Issuer and dates do not match the certificate on your server, for example the issuer is your CDN's certificate authorityA proxy terminates TLS; you are looking at its certificate, not your server's. Cloudflare's edge certificates can also come from Let's Encrypt, so check the origin directly
openssl shows fresh dates, but some visitors still get the errorAnother address answers part of the traffic: a stale AAAA record, a second server, an old load balancer

Then find out who manages the certificate. On a VPS, sudo certbot certificates lists every certificate Certbot handles, with its names, expiry date and file paths. On cPanel servers the job usually belongs to AutoSSL; on DirectAdmin, to the panel's built-in ACME client. If two tools manage the same name (for example Certbot installed by hand on a panel server), one replaces the certificate the other installed, or the web server keeps serving a copy that nobody renews. That is a common explanation for "renewed but still expired" reports.

2. How renewal works​

The ACME client (Certbot, AutoSSL, DirectAdmin, Caddy and others) asks Let's Encrypt for a certificate, receives a challenge for each name, proves that it controls the name and downloads the certificate. Let's Encrypt validates from several network locations and does not publish the IP addresses it uses, which matters for firewall rules.

  • HTTP-01: the client places a token file at http://example.com/.well-known/acme-challenge/TOKEN. Validation always starts on port 80. Let's Encrypt follows up to 10 redirects, only to http or https on ports 80 or 443, and it does not check the certificate of an HTTPS redirect target, so an expired certificate never blocks HTTP-01 by itself. It cannot issue wildcards.
  • DNS-01: the client publishes a TXT record at _acme-challenge.example.com. Required for wildcards (*.example.com); works behind proxies and for servers the internet cannot reach, but needs a DNS provider with an API.
  • TLS-ALPN-01: validation inside a TLS handshake on port 443, used by some servers and proxies such as Caddy. Certbot's plugins use HTTP-01 or DNS-01.

After a successful validation, Let's Encrypt caches the authorization for your account: currently for up to 30 days, and for 10 days from 10 February 2027. A certificate re-issued inside that window may skip validation entirely, so a manual re-run that "worked" proves little. A Certbot dry run is the better test, because it requests fresh authorizations from the staging server every time.

Where Certbot keeps its state and how it is scheduled:

Bash:
sudo certbot certificates                  # names, expiry and paths of every certificate
ls /etc/letsencrypt/renewal/               # one .conf per certificate: authenticator, webroot, hooks
systemctl list-timers | grep -i certbot    # is a renewal timer active?
sudo certbot renew --dry-run               # full test against staging, nothing is replaced
sudo certbot renew --cert-name example.com --dry-run   # test a single certificate
sudo less /var/log/letsencrypt/letsencrypt.log         # detailed log of the last run

How Certbot was installedSchedulerWatch out for
snapsnap.certbot.renew.timer, about twice a dayCurrent release, ARI included
apt on Debian and Ubuntucertbot.timer, plus /etc/cron.d/certbot for systems without systemdOlder releases: 2.1.0 on Debian 12, 2.9.0 on Ubuntu 24.04
dnf from Fedora or EPEL (AlmaLinux, Rocky Linux)certbot-renew.timerNot started at install: systemctl enable --now certbot-renew.timer
pip or a hand-made setupWhatever you createdOften nothing at all; check crontab -l and /etc/cron.d/

Certificates obtained with --manual do not renew on their own unless you supply an authentication hook script.

3. Error, cause, fix​

Certbot prints the certificate authority's verdict under "Certbot failed to authenticate some domains", one block per name:

Kod:
Certbot failed to authenticate some domains (authenticator: webroot). The Certificate Authority reported these problems:
  Domain: www.example.com
  Type:   unauthorized
  Detail: 2001:db8::10: Invalid response from http://www.example.com/.well-known/acme-challenge/x8Kq...: 404

Hint: The Certificate Authority failed to download the temporary challenge files created by Certbot. ...

Certbot 5.3.0 and later print Identifier instead of Domain. The address at the start of Detail is the IP address Let's Encrypt connected to when it failed; an IPv6 address there usually means the problem is on the IPv6 path (section 4). When Let's Encrypt itself rejects the validation, cPanel and DirectAdmin logs show the same texts.

Error (Detail)Usual causeFix
Timeout during connect (likely firewall problem)Port 80 is unreachable from the internet: cloud firewall or security group, ufw/firewalld, country blocking, or DNS pointing at an old IPOpen TCP 80 to all sources; check the A record; see section 4
Connection refusedNothing listens on port 80: web server only on 443, container port not published, standalone not runningAdd a port 80 listener; it can redirect everything except the challenge path to HTTPS
Invalid response from http://…/.well-known/acme-challenge/…: 404Wrong webroot, moved document root, the app or a rewrite rule takes the path, the HTTPS site behind the redirect serves from elsewhere, another server answersTest with a file (section 5); exclude the path from rewrites
The same with 403A rule that denies hidden paths, file permissions, an SELinux label, WAF or bot protectionAllow /.well-known/acme-challenge/ explicitly; check permissions and labels
The key authorization file from the server did not match this challengeAnother server or virtual host answered with a 200 page: old IP, stale AAAA, catch-all vhost, caching proxyCompare curl -4 and curl -6; fix DNS or the vhost
invalid host in redirect target "example.com.well-known"A redirect without the trailing slash (Redirect / https://example.com)Add the slash or exclude the challenge path
redirect loop detected; Received disallowed redirect status code 303Competing redirect rules; Let's Encrypt follows only 301, 302, 307 and 308 redirectsUse a single 301 redirect or exclude the challenge path
DNS problem: NXDOMAIN looking up A for www.example.com - check that a DNS record exists for this domainThe name has no record: deleted subdomain, missing www, typo, expired domain or domain pointerAdd the record or remove the name from the certificate
DNS problem: SERVFAIL looking up CAA for example.com - the domain's nameservers may be malfunctioning (or "DNSSEC: Bogus")Most often broken DNSSEC (for example a stale DS record left at the registrar after a DNS move); a nameserver that mishandles CAA queries; a nameserver outageCheck on dnsviz.net; fix or remove the DS record; contact the DNS provider
CAA record for example.com prevents issuanceA CAA record authorizes only another CAAdd 0 issue "letsencrypt.org"; if an issuewild record exists, it must allow letsencrypt.org too for wildcards
too many certificates (5) already issued for this exact set of identifiers in the last 168h0m0s, retry after …The same set of names issued again and again, usually while troubleshootingStop, test in staging, wait until the time given
too many failed authorizations (5) for "example.com" in the last 1h0m0s, retry after …Five failed validations within an hourFix the cause first; one attempt comes back every 12 minutes
Your account is temporarily prevented from requesting certificates for example.com and possibly others. Please visit: …Issuance for this name was paused after a long run of consecutive failuresFix the cause, then open the link to unpause
Could not bind TCP port 80 because it is already in use (Certbot, local)The standalone authenticator while a web server holds port 80Switch to webroot, nginx or apache (section 6)

Rate limits cannot be reset by hand, and revoking certificates does not reset them either. While you troubleshoot, use --dry-run or --staging: the staging environment has much higher limits.

4. Firewall, IPv6 and proxies​

Port 80 must be open to the world​

Because Let's Encrypt validates from several locations and does not publish its addresses, you cannot allow-list it. Rules that open port 80 only to Türkiye or to a few countries (country blocking in a cloud firewall, or CSF's country options) break HTTP-01 even though the site loads fine for you. Keep TCP 80 open to all sources and redirect visitors to HTTPS from there; if policy forbids that, use DNS-01. Check every layer: the provider's network firewall or security group, the host firewall (ufw, firewalld, nftables) and any appliance in between.

IPv6, the most overlooked cause​

When a name has an AAAA record, Let's Encrypt tries IPv6 first. It falls back to IPv4 only when the IPv6 connection cannot be established at all (refused, unreachable, connect timeout). If the IPv6 address accepts the connection and then answers wrongly, with a 404, another site, an old server or an error after connecting, validation fails without trying IPv4. Typical cases: the AAAA record still points at the previous server after a migration; the web server listens on IPv6 only in its default virtual host, so IPv6 requests for your site land there; the provider routes IPv6 to a different machine. Test both paths separately:

Bash:
dig +short A example.com
dig +short AAAA example.com
# after creating test.txt as in section 5; prints the status code and the IP that answered
curl -4 -sSLk -o /dev/null -w "%{http_code} %{remote_ip}\n" http://example.com/.well-known/acme-challenge/test.txt
curl -6 -sSLk -o /dev/null -w "%{http_code} %{remote_ip}\n" http://example.com/.well-known/acme-challenge/test.txt

If you do not serve the site over IPv6, delete the AAAA record instead of leaving it half working. Our DNS records guide explains AAAA and CAA records in more detail.

Cloudflare or another proxy in front​

With the proxy enabled (the orange cloud on Cloudflare), Let's Encrypt's request reaches the proxy first, which forwards it to your server. HTTP-01 keeps working as long as /.well-known/acme-challenge/ passes through untouched. It breaks when a WAF rule, bot protection or a page rule answers instead of your server. There is one more trap: an edge Always Use HTTPS redirect turns the challenge into an HTTPS request. If the proxy validates the origin certificate strictly, as Cloudflare does in Full (strict) mode, an origin certificate that has already expired produces error 526 and the token is never read. Your options:

  • Exempt the challenge path from security rules and edge redirects.
  • Switch the record to DNS only (grey cloud) for the renewal, then turn the proxy back on.
  • Use DNS-01 through your DNS provider's API (section 10). It is the most dependable option behind a proxy and the only one for wildcards.

5. Fixing 404 and 403 on the challenge path​

Reproduce the check yourself with a test file in the webroot your client uses (webroot_path in /etc/letsencrypt/renewal/example.com.conf). The example uses /var/www/letsencrypt, the directory we point Certbot at below; adjust the path if yours differs:

Bash:
sudo mkdir -p /var/www/letsencrypt/.well-known/acme-challenge
echo ok | sudo tee /var/www/letsencrypt/.well-known/acme-challenge/test.txt
curl -4 -iLk http://example.com/.well-known/acme-challenge/test.txt
curl -6 -iLk http://example.com/.well-known/acme-challenge/test.txt

You want a 200 with ok in the body over both IPv4 and IPv6. -L follows redirects and -k ignores certificate errors, as Let's Encrypt does; redirects are fine as long as they end at this file. A dedicated directory such as /var/www/letsencrypt keeps the path independent of the application and, on RHEL-family systems with SELinux, inherits a label the web server can read.

On Nginx, serve the path from that directory in the port 80 server block, before any redirect. The ^~ modifier stops regex locations, such as a rule that denies hidden files, from catching the request:

Kod:
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/letsencrypt;
        default_type "text/plain";
        try_files $uri =404;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

A return 301 placed directly in the server block runs before any location is chosen and redirects the challenge path too; move the redirect into location / as in the example. Then point Certbot at the directory once: sudo certbot reconfigure --cert-name example.com --webroot -w /var/www/letsencrypt

On Apache, exclude the path before the HTTPS redirect:

Kod:
Alias /.well-known/acme-challenge/ /var/www/letsencrypt/.well-known/acme-challenge/
<Directory "/var/www/letsencrypt/.well-known/acme-challenge/">
    Require all granted
</Directory>

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

With applications such as Laravel or WordPress, a 404 page from the application usually means the token was written to a different directory than the one the site serves (Laravel serves public/, for example), so the front controller answers instead. In deployments that switch a "current" symlink, a webroot that still points into an old release directory is another common cause. In containers, the ACME client and the web server must share the same challenge directory through a volume. For a 403, check rules like location ~ /\. { deny all; }, directory permissions, SELinux labels on custom paths and WAF rules such as ModSecurity.

6. Certbot fixes that stick​

Use the right authenticator​

Run grep -H authenticator /etc/letsencrypt/renewal/*.conf. standalone means Certbot opens port 80 itself, so it fails with "Could not bind TCP port 80" while Nginx or Apache is running. Switch to webroot, nginx or apache with certbot reconfigure. It is available from Certbot 2.3.0; it runs a test against staging and saves the change only if the test passes. Debian 12 ships 2.1.0, which lacks it: there, run certbot renew --cert-name example.com with the new options and --dry-run, and once that passes, run it again with --force-renewal, as the Certbot documentation describes.

Remove names that no longer exist​

A single name that no longer resolves makes the whole renewal fail. Re-issue the same certificate with only the names you keep: sudo certbot certonly --cert-name example.com -d example.com -d www.example.com, plus the authenticator options you use.

Clean up duplicate certificates​

example.com and example.com-0001 side by side usually means a later run created a second certificate. Check which path the web server loads (grep -R "letsencrypt/live" /etc/nginx /etc/apache2 /etc/httpd 2>/dev/null), then remove the unused one, for example with sudo certbot delete --cert-name example.com-0001.

Reload after renewal​

The nginx and apache plugins reload the server for you; webroot and standalone do not, so the new file sits on disk while the old certificate stays in memory. Add a deploy hook, which runs only after a successful renewal: save the script below as /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh (sudoedit works) and make it executable with sudo chmod 755.

Bash:
#!/bin/sh
# /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh
# Runs only after a successful renewal; $RENEWED_LINEAGE is the live/ directory
systemctl reload nginx
# systemctl reload postfix dovecot   # if mail services use the same certificate

Timer and version​

If systemctl list-timers shows no Certbot timer, enable the one your package provides (see the table in section 2) and read its log with journalctl -u certbot.service (certbot-renew.service on Fedora and EPEL, snap.certbot.renew.service for the snap). If the same machine has Certbot from both snap and apt or dnf, the command you run by hand and the one the timer runs may differ; Certbot's snap instructions also say to remove the package-manager Certbot first. If a renewal file names the nginx or apache plugin but the plugin is not installed, renewal stops with "The requested nginx plugin does not appear to be installed"; install python3-certbot-nginx or python3-certbot-apache. Finally, check certbot --version:

Certbot versionWhen it renewsShipped by (at the time of writing)
Before 4.0.030 days before expiry, unless renew_before_expiry says otherwiseDebian 12 (2.1.0), Ubuntu 24.04 (2.9.0), EPEL 9 (3.1.0)
4.0.xWhen a third of the lifetime remains (half for lifetimes of 10 days or less)Debian 13 and Ubuntu 26.04 (4.0.0)
4.1.0 and laterWhen Let's Encrypt suggests via ARI, typically at about two thirds of the lifetimeEPEL 10 (4.2.0), snap and pip (5.x)

All three handle 64-day certificates. What older releases miss is ARI: they cannot renew early when Let's Encrypt has to revoke certificates, and their renewals do not get the ARI exemption from rate limits. Also look for a hand-set renew_before_expiry in the renewal files; a small value such as a few days leaves no room for retries.

7. cPanel AutoSSL​

Let's Encrypt is the default AutoSSL provider for new installations of current cPanel & WHM; the Providers tab in Manage AutoSSL shows which provider is selected. AutoSSL runs for all users during the nightly update and from a daily cron job, and it tries to renew Let's Encrypt certificates once they are within 29 days of expiry. It includes only domains that pass domain control validation (DCV), so one failing name does not block the others, but that name stays unprotected. Because of rate limits, it gives new certificates priority over renewals.

  • Logs: WHM » Home » SSL/TLS » Manage AutoSSL, Logs tab. The files are in /var/cpanel/logs/autossl/ in text and JSON and are kept for 30 days.
  • Run it: in cPanel, Security » SSL/TLS Status » Run AutoSSL. The "Has AutoSSL Problems" filter shows affected domains, and the status column shows the logged error. As root: /usr/local/cpanel/bin/autossl_check --user=username (or --all). For the server hostname, cPanel's SSL guide points to /usr/local/cpanel/bin/checkallsslcerts, while the script's own page recommends running it only when cPanel support advises it.
  • Domain resolves elsewhere: DNS hosted at another provider still pointing at the old server, an AAAA record for another machine, or a proxy in front. HTTP-based DCV passes only when the request reaches this server.
  • Rewrites: .htaccess rules that send /.well-known/ to the application or to another host.
  • Service subdomains: cpanel., webmail., webdisk. and autodiscover. names without DNS records fail DCV and are skipped; add the records if you need them (the /usr/local/cpanel/scripts/servicedomains script can create them).
  • Other cases: suspended accounts get no certificates; CAA must allow letsencrypt.org (AutoSSL adds the record itself only in zones hosted on the server); wildcards need DNS hosted on the server or in its DNS cluster.

8. DirectAdmin​

Current DirectAdmin versions have a built-in ACME client (based on lego) that checks certificates every 24 hours. By default it renews after 65% of the lifetime has passed (acme_cert_lifetime_renew_threshold=0.65, with up to ±5% random jitter), which suits 64-day certificates. If renewal seems to have stopped by itself, check two settings first: acme_disable_after_failures=5 switches automatic issuance and renewal off for a certificate after five failed attempts, so after you fix the cause, request the certificate again yourself instead of waiting; and users hear about failed renewals only while letsencrypt_renewal_error_to_users keeps its default value of 1.

  • Where to look: User Level » SSL Certificates (ACME settings) to request again; Admin Level » Admin SSL for an overview of all domains; Server Manager » Server TLS Certificate for the hostname, which can also be renewed with /usr/local/directadmin/scripts/letsencrypt.sh server_cert.
  • Per-domain log: /usr/local/directadmin/data/users/USER/domains/acme_provider_cert_logs/DOMAIN.log. A missing log, or one with old timestamps, usually means DirectAdmin never tried.
  • Challenge path: echo test > /var/www/html/.well-known/acme-challenge/test.txt, then curl -I -L -k -X GET http://DOMAIN/.well-known/acme-challenge/test.txt. If the /.well-known alias is missing, da build rewrite_confs adds it; da build letsencrypt updates the client.

Migrations are a common trigger. After one, the DNS step in our cPanel to DirectAdmin migration guide deserves a second look: A and AAAA records must point at the new server, a CAA record carried over from the old setup may allow only a different CA, and a domain pointer whose DNS no longer works can fail the whole request with SERVFAIL. Wildcards need dns_ttl=1 and either a local DNS zone or a provider configured under User Level » SSL Certificates » Manage ACME DNS Providers.

9. Make renewal reliable before 64-day certificates​

  • Use an ARI-capable client: Certbot 4.1.0 and later, lego and Caddy (CertMagic) implement ARI (RFC 9773). Let's Encrypt's integration guide recommends checking ARI at least twice a day, and ARI renewals are exempt from all rate limits.
  • Remove fixed day counts: Let's Encrypt suggests searching cron jobs, wrapper scripts and runbooks for values like 60, 80 or 83 and renewing at about two thirds of the lifetime instead.
  • Automate every step after issuance: reloads, copies to load balancers, mail servers, appliances and Java keystores. With 64-day certificates a manual step comes round more often.
  • Monitor from outside: Let's Encrypt no longer emails you. Its Monitoring Service Options page lists services such as Red Sift Certificates Lite (free for up to 250 certificates); self-hosted options include a cron script or the probe_ssl_earliest_cert_expiry metric of Prometheus blackbox_exporter.
  • Alert on failure, not only on expiry: certbot renew exits with status 1 when a renewal fails, so the timer's service ends up in the failed state (systemctl is-failed certbot.service; the unit name depends on your install). Post hooks receive the failed names in FAILED_DOMAINS from Certbot 4.2.0; the variable was documented in 2.7.0 but stayed empty on failure until 4.2.0.
  • Several servers: route /.well-known/acme-challenge/ from every node to the one that runs the client, or issue once with DNS-01 and distribute the files with a deploy hook. Nodes that each request the same set of names compete for the limit of 5 per week.

Bash:
# Find hard-coded renewal intervals (expect some false positives)
sudo grep -RnE -- '--days|renew_before_expiry|force-renew|(^|[^0-9])(60|80|83)([^0-9]|$)' \
  /etc/cron* /var/spool/cron /etc/systemd/system /etc/letsencrypt/renewal /usr/local/bin 2>/dev/null

# Daily external check: run from cron on another machine; cron emails any output
# to MAILTO (or the job owner) if that machine can send mail
for host in example.com www.example.com; do
  echo | openssl s_client -connect "$host:443" -servername "$host" 2>/dev/null \
    | openssl x509 -noout -checkend 864000 >/dev/null \
    || echo "$host: certificate expires within 10 days or could not be read"
done

A post hook that logs failed renewals (Certbot 4.2.0+); make it executable like the deploy hook:

Bash:
#!/bin/sh
# /etc/letsencrypt/renewal-hooks/post/alert-on-failure.sh
[ -n "$FAILED_DOMAINS" ] && logger -t certbot "renewal failed for: $FAILED_DOMAINS"
exit 0

For mail servers, check port 993 with the same command, or port 587 with -starttls smtp. Set alert thresholds to the new lifetimes: a monitor that warns at 30 days left fires for every healthy 64-day certificate, and people learn to ignore it. The warning thresholds below are suggestions:

LifetimeRenew at about two thirdsDays left at renewalWarn below
90 days (until 10 February 2027)Day 60About 3015 days
64 days (default from 10 February 2027)Day 42 or 43About 2110 days
45 days (planned default from February 2028)Day 30About 157 days

10. Wildcards with DNS-01 and a scoped API token​

Wildcard certificates require DNS-01, so pick a DNS host with a solid API; our comparison of managed DNS services covers Cloudflare, Route 53, BunnyDNS and NS1. With Cloudflare, create an API token that has only Zone:DNS:Edit for the zones you need, never the Global API Key, and install the certbot-dns-cloudflare plugin (the plugin snap, or python3-certbot-dns-cloudflare on Debian and Ubuntu). The credentials file needs one setting:

INI:
# /root/.secrets/certbot/cloudflare.ini
dns_cloudflare_api_token = PASTE_A_TOKEN_LIMITED_TO_ZONE_DNS_EDIT

Bash:
# Plugin: the first two lines for the snap, the third for the Debian/Ubuntu package
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare
# sudo apt install python3-certbot-dns-cloudflare

sudo install -d -m 700 /root/.secrets/certbot
sudoedit /root/.secrets/certbot/cloudflare.ini        # paste the line above
sudo chmod 600 /root/.secrets/certbot/cloudflare.ini

sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/certbot/cloudflare.ini \
  --dns-cloudflare-propagation-seconds 60 \
  -d example.com -d '*.example.com'

A token on the web server can still change DNS records in its zones. To shrink that risk, you can point _acme-challenge.example.com with a CNAME at a record in a separate zone used only for validation: Let's Encrypt follows CNAME and NS delegation for DNS-01. Your client has to support that layout too; Certbot DNS plugins such as certbot-dns-cloudflare write the record into the domain's own zone, while acme-dns is a small DNS server built for exactly this job. The other route is to run DNS-01 on a separate host and copy the certificates to the web servers. Remove old _acme-challenge TXT records, because Let's Encrypt rejects responses that grow too large. Let's Encrypt has also announced DNS-PERSIST-01, in which a one-time TXT record at _validation-persist.example.com authorizes your ACME account; check its current availability and your client's support before you plan around it.

Checklist​

  • openssl from outside shows the expected issuer, names and dates for every hostname, over IPv4 and IPv6.
  • Exactly one tool manages each certificate.
  • TCP 80 is open to the whole internet, or the certificate uses DNS-01.
  • Every AAAA record points to a server that serves the same site.
  • A test file under /.well-known/acme-challenge/ returns 200 for every name in the certificate.
  • No CAA record excludes letsencrypt.org, and DNSSEC validates (dnsviz.net).
  • The certificate lists only names that still resolve.
  • sudo certbot renew --dry-run succeeds, or the panel's manual run succeeds.
  • A timer or cron job exists and has run recently.
  • A deploy hook reloads every service that uses the certificate.
  • No job, script or runbook renews on a fixed day count.
  • External expiry monitoring with thresholds that suit 64-day certificates, plus an alert when a renewal fails.

FAQ​

The certificate has already expired. What is the fastest safe fix?
Run sudo certbot renew --dry-run, or the panel's AutoSSL or ACME check, and fix the error it reports. Then run sudo certbot renew once and, if you have no deploy hook, reload the web server. Do not retry --force-renewal in a loop: failed validations count towards the hourly limit, and repeated re-issues towards the weekly one.

Nothing changed on my server. Why did renewal stop?
Usually something around it changed: DNS, a new AAAA record, a firewall or proxy rule, a deleted subdomain still listed in the certificate, a disabled timer or, on DirectAdmin, automatic renewal switched off after repeated failures.

Do I need to change anything for 64-day certificates?
Not if your client uses ARI or renews at about two thirds of the lifetime. Search for fixed intervals, adjust monitoring thresholds and run a dry run; staging has issued 64-day certificates since 14 October 2026.

Can I renew while the site is behind Cloudflare?
Yes. HTTP-01 works if the challenge path reaches your server unchanged; otherwise use DNS-01 with a scoped API token. Wildcards always need DNS-01.

I hit a rate limit. Can it be reset?
No, and revoking certificates does not reset it either. Fix the cause, test in staging and wait until the time in the error; the limit of 5 certificates per exact set of names regains one certificate every 34 hours.

Conclusion and next steps​

Renewal failures come down to a short list: port 80 closed, DNS or IPv6 pointing somewhere else, rewrite and proxy rules catching the challenge path, CAA or DNSSEC errors, and servers that never reload the new file. Today, run a dry run on every server, compare IPv4 and IPv6 answers and set up external expiry monitoring. Before 10 February 2027, replace fixed-interval renewal jobs, move to an ARI-capable client and automate every reload and copy step. If you need an organization-validated certificate, or would rather have installation handled as a service, AIOR's SSL certificate service is one option. Still stuck? Post the full Detail line and a short description of your setup in this thread.
 

Forum istatistikleri

Konular
925
Mesajlar
932
Üyeler
26
En son üye
Jessicawatson

Çevrimiçi üyeler

Şu anda çevrimiçi üye yok.

Öne çıkan içerik

AIOR
AIOR TEKNOLOJİ

Tüm ihtiyaçlarınız için Teklif alın

Hosting · Domain · Sunucu · Tasarım · Yazılım · Mühendislik · Sektörel Çözümler

Teklif al

7/24 Destek · Anında yanıt

Geri
Üst