A Certbot webroot challenge is useful when an existing public HTTP site must keep serving traffic while ACME validation runs. Certbot writes a temporary challenge file below the site's document root, and the certificate authority must retrieve that exact file through the requested hostname on port 80.
The webroot plugin is an authenticator, not an installer. It can obtain certificate files under /etc/letsencrypt/live without stopping the web server or editing Nginx or Apache, but the web server configuration still needs to serve the challenge path during issuance and use the resulting certificate paths afterward.
The examples use one webroot for site.example.net and www.site.example.net. When hostnames use different document roots, place the matching -w option before the -d names that belong to that root, and use a DNS-01 challenge instead for wildcard names, private-only services, or sites where port 80 cannot be reached from the public Internet.
Related: Use a DNS challenge with Certbot
Related: Install a Certbot certificate for Nginx
$ getent ahosts site.example.net 203.0.113.10 STREAM site.example.net 203.0.113.10 DGRAM 203.0.113.10 RAW
If the name also has an .AAAA record, that IPv6 address must serve the same challenge path or HTTP-01 validation can fail over IPv6.
$ curl -I http://site.example.net/ HTTP/1.1 200 OK Server: nginx/1.28.0 ##### snipped #####
HTTP-01 starts on port 80. Redirects can work when they preserve the challenge URL and stay on ports 80 or 443, but redirects to login pages, other hosts, or blocked hidden directories will fail validation.
$ sudo nginx -T
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/sites-enabled/site.example.net:
server {
listen 80;
server_name site.example.net www.site.example.net;
root /var/www/site.example.net;
}
##### snipped #####
Use the directory served by the matching virtual host. On Apache, this is usually the matching DocumentRoot instead of the Nginx root directive.
$ sudo mkdir -p /var/www/site.example.net/.well-known/acme-challenge
Certbot can create its own challenge files, but creating the directory first exposes hidden-directory and permission problems before the ACME request.
$ printf 'challenge-ok\n' | sudo tee /var/www/site.example.net/.well-known/acme-challenge/probe-token challenge-ok
$ curl http://site.example.net/.well-known/acme-challenge/probe-token challenge-ok
The body should be only the probe text. Repeat the check from outside the origin network when a load balancer, CDN, WAF, or separate IPv6 listener can change the route.
Tool: ACME HTTP 01 Readiness Validator
$ sudo certbot plugins Saving debug log to /var/log/letsencrypt/letsencrypt.log ##### snipped ##### * webroot Description: Saves the necessary validation files to a .well-known/acme-challenge/ directory within the nominated webroot path. A separate HTTP server must be running and serving files from the webroot path. HTTP challenge only (wildcards not supported). Interfaces: Authenticator, Plugin ##### snipped #####
$ sudo certbot certonly --webroot -w /var/www/site.example.net -d site.example.net -d www.site.example.net -m admin@example.net --agree-tos --non-interactive --dry-run Saving debug log to /var/log/letsencrypt/letsencrypt.log Simulating a certificate request for site.example.net and www.site.example.net The dry run was successful.
For domains served from different document roots, place the matching -w option before the -d names that use that webroot. --dry-run uses the staging service and does not save a production certificate.
Related: Use the Certbot staging environment
$ sudo certbot certonly --webroot -w /var/www/site.example.net -d site.example.net -d www.site.example.net -m admin@example.net --agree-tos --non-interactive Saving debug log to /var/log/letsencrypt/letsencrypt.log Requesting a certificate for site.example.net and www.site.example.net Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/site.example.net/fullchain.pem Key is saved at: /etc/letsencrypt/live/site.example.net/privkey.pem
This command obtains the certificate only. Install /etc/letsencrypt/live/site.example.net/fullchain.pem and /etc/letsencrypt/live/site.example.net/privkey.pem in the web server configuration before expecting HTTPS traffic to use the new certificate.
$ sudo certbot certificates --cert-name site.example.net
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Found the following certs:
Certificate Name: site.example.net
Domains: site.example.net www.site.example.net
Expiry Date: 2026-09-10 12:00:00+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/site.example.net/fullchain.pem
Private Key Path: /etc/letsencrypt/live/site.example.net/privkey.pem
$ sudo certbot renew --cert-name site.example.net --dry-run Saving debug log to /var/log/letsencrypt/letsencrypt.log Processing /etc/letsencrypt/renewal/site.example.net.conf Congratulations, all simulated renewals succeeded: /etc/letsencrypt/live/site.example.net/fullchain.pem (success)
A successful renewal dry run confirms that Certbot can reuse the saved webroot authenticator and challenge path later.
Related: Test Certbot certificate renewal
Related: Check the Certbot renewal timer
$ sudo rm /var/www/site.example.net/.well-known/acme-challenge/probe-token
Certbot removes its own ACME challenge files after validation. Removing the manual probe keeps the challenge directory from serving stale test content.