# Domain points at your VPS but the site or certificate fails

> The domain should reach your server but the site doesn't load, or certbot fails. Check DNS, reachability, the nginx site and the certificate, in that order.

Source: https://rack4.io/tutorials/troubleshoot-domain-and-https · Updated: 2026-11-06

Difficulty: intermediate · Time: about 20 minutes · Tested on: Ubuntu 24.04 LTS, Debian 13 Stable

Prerequisites:

- A domain you control
- A server running nginx
- Root or sudo access to the server

When a domain that should reach your server doesn't work, the cause is in one of four layers. Check them in this order and stop at the first one that fails: DNS (does the name lead to your server's address?), reachability (do ports 80 and 443 answer?), the site (does nginx serve the right site for that name?), and the certificate.

This page uses `example.com` for your domain and `203.0.113.42` for your server's address; use your own. Setting the domain up the first time is covered in [How to point a domain at your VPS](https://rack4.io/tutorials/point-a-domain-to-your-vps); this page is for when it doesn't work.

## 1. DNS: does the name lead to your server?

Ask from your own computer, and from a public resolver, so you're not looking at a stale copy:

```bash
dig +short NS example.com
dig +short A example.com @one.one.one.one
dig +short AAAA example.com @one.one.one.one
```

(On Windows without `dig`: `nslookup -type=A example.com one.one.one.one`.)

- **NS**: these are the servers that answer for your domain, and the only place where record changes count. If they aren't the provider where you edited the records, your edits have no effect. Edit them where the NS records point, or change the nameservers at your registrar.
- **A**: must be your server's IPv4 address, exactly, and only that one. An old address here, from a previous server or host, sends visitors and Let's Encrypt to the wrong machine.
- **AAAA**: if there's an IPv6 record, it must be an IPv6 address your server actually answers on. Browsers and Let's Encrypt try IPv6 first when a domain has one, so a wrong or stale AAAA record breaks things even when the A record is right. Rack4 servers don't have an IPv6 address yet ([Check that IPv6 works](https://rack4.io/help/ipv6-setup) says when), so a domain pointing at a Rack4 server should have **no** AAAA record for now. Delete it if there is one.

If you've just changed a record, an answer can stay cached for as long as the record's old TTL. Comparing `@one.one.one.one` with `@dns.google` shows whether resolvers have caught up.

## 2. Reachability: do ports 80 and 443 answer?

From your computer, send a request straight to the server's address, with the domain name attached, so DNS isn't involved:

```bash
curl -sI --resolve example.com:80:203.0.113.42 http://example.com/
```

- **An HTTP status line** (`HTTP/1.1 200`, `301`, `404`…): the server is reachable. Go to step 3.
- **`Connection refused`**: the address answered, but nothing accepts connections on port 80. Check nginx is running (`systemctl status nginx`) and listening (`sudo ss -ltnp | grep -E ':80|:443'`), and that a firewall isn't rejecting the port.
- **A timeout**: nothing answered. A firewall is dropping the traffic: `ufw` or `firewalld` on the server ([Check open ports](https://rack4.io/tutorials/check-open-ports-linux)), or the [panel firewall](https://rack4.io/help/server-firewall). Ports 80 and 443 must both be open for a website, and port 80 for certbot's usual check.

## 3. The site: is nginx serving the right one?

If the server answers but shows the wrong site, the default "Welcome to nginx" page, or a 404, nginx didn't match your domain to your site. List the names it knows:

```bash
sudo nginx -T 2>/dev/null | grep -E 'server_name|listen'
```

Your domain (and `www.` if you use it) must appear in a `server_name` line, in a file that's enabled (in `/etc/nginx/sites-enabled/` on Ubuntu and Debian). Fix it, then `sudo nginx -t && sudo systemctl reload nginx`, and repeat the `curl --resolve` test. A 502 or 504 at this point is a different problem: see [Fix nginx 502 and 504](https://rack4.io/tutorials/fix-nginx-502-504).

If you use Cloudflare's proxy (the orange cloud), `dig` shows Cloudflare's addresses, not yours, and Cloudflare's SSL mode matters too: **Full (strict)** needs a valid certificate on your server. While you're fixing things, switching the record to **DNS only** takes Cloudflare out of the picture.

## 4. The certificate: why certbot failed

certbot proves you control the domain by having Let's Encrypt fetch a file from `http://example.com/.well-known/acme-challenge/…`. When that fails, certbot prints what Let's Encrypt saw. The `Detail:` line is the one that matters, and it starts with the **address Let's Encrypt connected to**. Compare it with your server's address first.

These are the messages we got on a test server:

**The name points at another machine:**

```text
Domain: example.com
Type:   connection
Detail: 198.51.100.7: Fetching http://example.com/.well-known/acme-challenge/…: Connection refused
```

The address in `Detail:` isn't your server's. Fix the A record (step 1), wait for it to spread, then run certbot again.

**Port 80 is rejected:**

```text
Detail: 203.0.113.42: Fetching http://example.com/.well-known/acme-challenge/…: Connection refused
```

It's your address this time, so DNS is right but port 80 refused the connection: nginx isn't listening on it, or a firewall rule rejects it. Fix it as in step 2.

**Port 80 is silently dropped:**

```text
Detail: 203.0.113.42: Fetching http://example.com/.well-known/acme-challenge/…: Timeout during connect (likely firewall problem)
```

A firewall is dropping traffic to port 80. Open port 80; certbot needs it even if your site redirects everything to HTTPS.

**Other messages you may meet:**

- `Type: unauthorized` with `Invalid response … 404`: Let's Encrypt reached a web server, but the challenge file wasn't there. Usually the request reached a different site or a different server (a stale A or AAAA record, or a CDN in front), or a redirect rule caught `/.well-known/`.
- `Type: dns` with `NXDOMAIN` or `no valid A records`: the name doesn't exist in DNS yet, or has a typo.
- `CAA record … prevents issuance`: your domain has CAA records that don't list Let's Encrypt. Check with `dig +short CAA example.com`; add `0 issue "letsencrypt.org"` or remove the CAA records.
- `too many certificates already issued` or `too many failed authorizations`: you've hit Let's Encrypt's rate limits by retrying. Fix the cause first, and test with `certbot --test-cert`, which uses Let's Encrypt's staging service and doesn't count against the real limits.

When it works, certbot says `Successfully received certificate.` Check what visitors get:

```bash
curl -sI https://example.com/ | head -1
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -subject -dates
```

The subject should name your domain, and the dates should include today.

## Renewals that fail later

certbot renews certificates automatically; the same four layers break renewals too, often months later, after a firewall or DNS change. Test the renewal without waiting:

```bash
sudo certbot renew --dry-run
```

and fix whatever it reports with the steps above.

We produced the certbot messages on this page on 6 November 2026 on a Rack4 server running Ubuntu 24.04 with nginx 1.24 and certbot 2.9, using Let's Encrypt's staging service: a name pointing at another server, port 80 rejected, port 80 dropped, and a working setup. The "other messages" and the AAAA, CAA and Cloudflare notes come from Let's Encrypt's and Cloudflare's documented behaviour, not from that test.
