Let's Encrypt SSL Cert Auto-Renew "Internal Error"
Checklist
- Have you pulled and found the error with
jc21/nginx-proxy-manager:latestdocker image?- Yes
- Are you sure you're not using someone else's docker image?
- Yes
- Have you searched for similar issues (both open and closed)?
- Yes
Describe the bug Certificates issued by Lets Encrypt does not auto renew, manually clicking renew returns "Internal Error". Deleting the certificate and re-creating it works though.
Nginx Proxy Manager Version
v2.11.3 - Using Docker-Compose
To Reproduce Steps to reproduce the behavior:
- Find expired lets encrypt cert.
- Click renew (returns "Internal Error")
Expected behavior
Renew the ssl certificate issued by Lets Encrypt
Screenshots
Operating System
Distributor ID: Debian
Description: Debian GNU/Linux 12 (bookworm)
Release: 12
Codename: bookworm
I've the same problem with the same docker version
I've the same problem with the same docker version
Im using the docker-compose version too. Forgot to mention that.
Deleting the certificate and re-creating it works though.
I added a DNS Challenge cert for a domain that I havent used before, after adding it I was able renew the other certificates without getting the Internal Error!
Edit: Came across this error again with another docker compose container. I recently migrated this container to a new machine and the symlink's located in the "./letsencrypt/live/npm-x/" directory were copied over as the source files, not the links. After recreating the symlinks to the ".pem" files located at "./letsencrypt/archive/npm-x/" I was able to renew the cert.
Deleting the certificate and re-creating it works though.
I added a DNS Challenge cert for a domain that I havent used before, after adding it I was able renew the other certificates without getting the Internal Error!
Edit: Came across this error again with another docker compose container. I recently migrated this container to a new machine and the symlink's located in the "./letsencrypt/live/npm-x/" directory were copied over as the source files, not the links. After recreating the symlinks to the ".pem" files located at "./letsencrypt/archive/npm-x/" I was able to renew the cert.
I am using the DNS Challenge and i still get this error.
I recently migrated this container to a new machine and the symlink's located in the "./letsencrypt/live/npm-x/" directory were copied over as the source files, not the links.
My links are correct (just checked). The renew just never ever worked for me. This is my second NPM and still does not work.
I checked the logs because of the same issue and I got banned from letsencrypt. I was horrified to discover that I got banned because NPM was SPAMMING the renewal requests for domains that were not even accessible, multiple times a minute. As I am quite sure this not how it worked, I believe this a bug introduced with a recent version.
" error: urn:ietf:params:acme:error:rateLimited :: There were too many requests of a given type"
I checked the logs because of the same issue and I got banned from letsencrypt. I was horrified to discover that I got banned because NPM was SPAMMING the renewal requests for domains that were not even accessible, multiple times a minute. As I am quite sure this not how it worked, I believe this a bug introduced with a recent version.
" error: urn:ietf:params:acme:error:rateLimited :: There were too many requests of a given type"
What is the location of the log file. Maybe i missed something. My log files don't show any errors.
FYI: for anyone else that is in the same situation as me this is the fix.
I limited my CloudFlare API key to only work from certain IP addresses. I recently moved house and changed my ISP. Since then the Cert Renewals all failed with the same error that OP listed, But I had forgotten this.
After checking the /var/logs/letsencrypt/letsencrypt.log file I could see multiple of the following entries:
2024-10-24 08:23:29,249:DEBUG:certbot_dns_cloudflare._internal.dns_cloudflare:Encountered error finding zone_id during deletion: Error determining zone_id: 9109 Max auth failures reached, please check your Authorization header.. Please confirm that you have supplied valid Cloudflare API credentials. (Did you enter a valid Cloudflare Token?)
This indicated an issue with my API key. Knowing I had not changed it, I logged into the Cloud Flare and noticed I had restricted it to only be usable from certain IP addresses, as security precaution. After entering in my new (static) IP from the new ISP the issue was resolved (for me in this very specific situation).
I hope this help anyone else that may have limited their API key to certain IP address, and forgot they did that. :)
Solved by force containers removal, pruning latest images and re-creating it again by pulling the latest version:
docker rm -f npm-app docker rm -f npm-db docker image prune -a docker-compose up -d
Hope it helps!
Hello got same issue, which DNS are you using ? If its cloudflare, desactivate cloudflare proxy (test but wait a few minutes), get your ssl certs and put cloudlfare proxy again. Otherwise for other DNS use nslookup <your_domain> and verify its your ip.
Had similar issue today, my ssl 's usual auto renew and not been an issue for a few years, today noticed one ssl needed to be renewed by 24th Nov 2024, tried to manually renew but got an internal error.
Googled and saw one post on here to say to switch off forced SSL and try, so did this and manual renew worked, not sure why its started to be an issue now and no before, Ive always had force ssl on.
Use nginx in Unraid, docker, repo: jlesage/nginx-proxy-manager
Also using cloudflare cname record with proxy enabled.
thanks
I have the same issue, switched off force SSL but still no success in renewing. And when I test server connectivity in NPM it says:
influxdb.
The mentioned internal ip-address: 192.168.178.10:8086 is valid and I can connect directly through that.
A bit later: About a month ago I've put my Raspberry Pi4 in another network. Seemed that port 80 wasn't forwarded from the Fritzbox to the RPi4. So after modifying this it's working again.
I have the same error, I need to disable the proxy and then manual renewal works.
So if I have a domain example.com which is pointet to my NPM which in turn redirects to 192.168.178.1 or something like that I need to disable the proxy, renew the certificate and after the renewal enable the proxy host again. This is a workaround for me but automatic renewal would be good.
just hit the same issue 2 days ago, i rotated my CF DNS challenge api key before trying turning off the options some people suggested, i now realize the API key had been blacklilsted as per others in this thread
was very surprised there is no way to edit existing cert entry to change API key - this should be a mandatory high prio feature in my opinion
i would go one step further and say it should be stored as docker secret and not stored in the db or a normal text file
deleting the old cert entry, creating new one for the rotated key works
log errors if it helps the devs:
this was on version 12.2 - note i may have hit error on earlier initially on earlier version but i force pulled the latest as part of my troubleshooting, and whatever broke on earlier image was still broken.
I am fairly certain the API key was invalidated for some reason, none of my other 12 A keys for ACME on the same account / domain / zones were invalidated (i use unique key for each acme process i have, so this as something specific to this key and i would hazard validates the assertion someone made that API was invalidate due to abuse from npm as they describe above)
[1/15/2025] [8:32:46 PM] [SSL ] › ℹ info Renewing Let'sEncrypt certificates via Cloudflare for Cert #1: *.foo.com, foo.com
[1/15/2025] [8:32:46 PM] [SSL ] › ℹ info Command: certbot renew --force-renewal --config "/etc/letsencrypt.ini" --work-dir "/tmp/letsencrypt-lib" --logs-dir "/tmp/letsencrypt-log" --cert-name 'npm-1' --disable-hook-validation --no-random-sleep-on-renew
[1/15/2025] [8:32:46 PM] [Global ] › ⬤ debug CMD: certbot renew --force-renewal --config "/etc/letsencrypt.ini" --work-dir "/tmp/letsencrypt-lib" --logs-dir "/tmp/letsencrypt-log" --cert-name 'npm-1' --disable-hook-validation --no-random-sleep-on-renew
[1/15/2025] [8:32:48 PM] [SSL ] › ✖ error Saving debug log to /tmp/letsencrypt-log/letsencrypt.log
Failed to renew certificate npm-1 with error: Error determining zone_id: 9109 Invalid access token. Please confirm that you have supplied valid Cloudflare API credentials. (Did you enter a valid Cloudflare Token?)
All renewals failed. The following certificates could not be renewed:
/etc/letsencrypt/live/npm-1/fullchain.pem (failure)
1 renew failure(s), 0 parse failure(s)
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /tmp/letsencrypt-log/letsencrypt.log or re-run Certbot with -v for more details.
During Let's Encrypt Certificate Renewal When "Force HTTPS" is disabled, the certificate renewal works without issues. However, if "Force HTTPS" is enabled, the renewal process will fail. I think Let's Encrypt needs to access the ACME challenge at http://domain.com/.well-known/acme-challenge/. I believe this is because Let's Encrypt attempts to access the ACME challenge over HTTPS, but the challenge needs to be accessed via HTTP. Reason: If "Force HTTPS" is enabled, the challenge URL gets redirected to HTTPS, which prevents Let's Encrypt from verifying the domain correctly. Solution: Disable "Force HTTPS" temporarily during the certificate renewal to allow Let's Encrypt to access the challenge over HTTP and complete the verification.
I'm having a similar problem to everyone else. My certs aren't auto-renewing, I get an email saying they're expiring soon and we won't get emails anymore in the near future. If I go to the SSL tab and choose "Renew Now" it tries for a bit and then returns "Internal Error" and that's it. If go into proxy tab, edit the same one that just failed and manually choose to create a new cert on the SSL tab, it works and then I can delete the previous cert from the SSL section.
Additionally, if I first go into a proxy and disable 'Force SSL' and go to the SSL page and choose that one to "Renew Now" it renews perfectly well with no internal errors, and I don't have to manually delete the previous cert. I then have to go back to Proxy and reenable "Force SSL".
Solved by force containers removal, pruning latest images and re-creating it again by pulling the latest version:
docker rm -f npm-app docker rm -f npm-db docker image prune -a docker-compose up -d
Hope it helps!
I was running into this error on npm latest version using DNS challenge with registrar API. The steps above from @coolstuff99 saved me.
During Let's Encrypt Certificate Renewal When "Force HTTPS" is disabled, the certificate renewal works without issues. However, if "Force HTTPS" is enabled, the renewal process will fail.
This is not correct! I have more than 10 local web apps running with external access through NPM and I have "Force HTTPS" on all of them and never ever had any LE certificate update problems. It's all automatic.
Hi everyone. I am having the same issue. I started receiving emails from Letsencrypt and did not think much of it. I tried switching off proxy on CF but still get internal error on NPM. I tried switching "force SSL", it still fails. I tried creating a new SSL in NPM SSL tab, and I get this error:
CommandError: Saving debug log to /tmp/letsencrypt-log/letsencrypt.log An unexpected error occurred: requests.exceptions.ConnectionError: HTTPSConnectionPool(host='acme-v02.api.letsencrypt.org', port=443): Max retries exceeded with url: /directory (Caused by NameResolutionError(": Failed to resolve 'acme-v02.api.letsencrypt.org' ([Errno -3] Temporary failure in name resolution)")) Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /tmp/letsencrypt-log/letsencrypt.log or re-run Certbot with -v for more details.
at /app/lib/utils.js:16:13
at ChildProcess.exithandler (node:child_process:430:5)
at ChildProcess.emit (node:events:518:28)
at maybeClose (node:internal/child_process:1104:16)
at ChildProcess._handle.onexit (node:internal/child_process:304:5)
Also, when I try the site reachability test I get this error:
Failed to check the reachability due to a communication error with site24x7.com.
I've been using NPM for years. Never encountered this issue before. Any ideas?
Ok, just an update for anyone that might have the same issue as I did, I managed to fix it by adding the following lines to my compose file:
dns:
- 1.1.1.1
- 8.8.8.8
Turns out nginx was not able to resolve any domains. not sure when this issue started. As I mentioned I've had this setup for years without any issues. Hope this helps someone!
The solution for me was to use the Global API Key instead of an API token, specifically for DNS management. You can find this key at: https://dash.cloudflare.com/profile/api-tokens
Ok, just an update for anyone that might have the same issue as I did, I managed to fix it by adding the following lines to my compose file:
dns: - 1.1.1.1 - 8.8.8.8Turns out nginx was not able to resolve any domains. not sure when this issue started. As I mentioned I've had this setup for years without any issues. Hope this helps someone!
Had the issue again and this solved it for this time. Thanx.
This is as much a reminder for future me as it is a hint for anyone who might encounter a similar situation. If you receive the "internal error" in Nginx Proxy Manager and you're using Namecheap (possible others as well) as your DNS provider, always check that your current IP (the server one that your NPM instance is using of course) is whitelisted for API access under namecheap.com -> account -> tools -> API access.
So none of the solutions above worked for me and I had the same symptoms (auto-renew not working and manually trying to do so in npm gave me an "internal error". The hint to my solution lied in the certbot log. This log is hard to find and is the reason why the letsencrypt people don't like NPM and will refuse to help you troubleshoot this issue. So let's go on a tangent to help you solve that problem first:
This certbot log is stored inside the npm container under /tmp/letsencrypt.log (older ones are stored in /tmp/letsencrypt.log.# where # is an incrementing number). You can access this file by doing sudo docker exec -it <insert your container ID here> bash or you can expose it to the host file system by adding the last line to your docker compose like the following.
`volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt - ./tmp:/tmp/letsencrypt-log``
ok back to the solution for my problem. In my log file I saw the following excerpt:
"error": { "type": "urn:ietf:params:acme:error:connection", "detail": "MyIP.MyIP.MyIP.MyIP: Fetching http://mywebsite.com/.well-known/acme-challenge/->KfXt9CXtKjQmN4mOpm8wVLTVEf2CwBtWRm1eRm6LJI: Connection refused", }
The letsencrypt certbot has a couple different methods it can use to verify that you own control of your domain. One of those is http and the way it works is that it gives you a special number to store in a file on your domain and then it will go and check if it exists. If the file (with the right number) is there then you proved you own the domain. What this error is telling is that it tried to find the file and the webserver said no one is here, go away AKA the port is not open. And remember that this is http and not https so we're talking about port 80.
My NPM docker container's docker compose yaml had the following excerpt:
ports: - '443:443'
This meant that the host SSL port 443 was connected to the container but not port 80. I changed it to read:
ports: - '443:443' - '80:80'
and then brought the container down and then back up. On container startup, NPM will try and renew and expired (or soon to expire) certs. Upon checking the tmp/letsencrypt.log again, I could see that it was very different and didn't have the connection refused errors.
Long story short, mapping host port 80 to the NPM container resolved the problem for me.