Compare the platform address with the custom domain
Request both and compare status, Location and Server headers before changing anything. If one stalls or truncates and the other does not, test IPv4 and IPv6 separately to see whether the two hostnames take different network paths. We found no single documented cause for stalled or truncated responses, so treat the result as a way to isolate the problem, not a diagnosis.
curl -sSI https://your-app.vercel.app | head -20
curl -sSI https://example.com | head -20
curl -4 -sS -o /dev/null -w '%{size_download}\n' https://example.com/app.js
curl -6 -sS -o /dev/null -w '%{size_download}\n' https://example.com/app.js
Check DNS against what the platform asks for
Read the records the host shows in its domain settings and compare them with what resolves. Remove outdated A, AAAA or CNAME records, make the AAAA record match the A record's destination or delete it, and look for stray NS and CAA records.
dig +short A example.com
dig +short AAAA example.com
dig +short CNAME www.example.com
dig +short NS example.com
dig CAA example.com +noall +answer
Fix the proxy's connection to the origin
For a redirect loop behind Cloudflare, set SSL/TLS to Full (strict) with a valid certificate on the origin, or remove the origin's HTTPS redirect if you must stay on Flexible. Remove any origin rule that sends HTTPS back to HTTP, and check Redirect Rules and Page Rules for two rules pointing at each other. Vercel's own HTTP-to-HTTPS redirect cannot be disabled, so on Vercel the proxy has to connect over HTTPS.
Keep the validation path open, including for renewals
On port 80, let /.well-known/acme-challenge/* (and /.well-known/pki-validation/* on Cloudflare) through without caching, authentication, rewrites or redirects. In a Cloudflare HTTP-to-HTTPS Redirect Rule, exclude the path with: (http.request.scheme eq "http") and not starts_with(http.request.uri.path, "/.well-known/"). If the proxy cannot be made transparent, point DNS straight at the host (DNS only in Cloudflare), as both Vercel and Netlify advise for issuance.
Clear stale validation records and resolve ownership
Look for a leftover challenge TXT record from a previous provider, and keep any NS record that deliberately delegates validation. If the platform says another account owns the domain, move it from that account, or use the host's external-connect option and add the TXT record it gives you.
dig +short TXT _acme-challenge.example.com
Fix the cause before you retry issuance
Run a public checker such as Let's Debug or DNSViz, correct what it finds, then trigger issuance once. If you are already rate limited, wait out the window or switch to another CA where your plan allows it. Cloudflare says most Let's Encrypt limits clear within 7 days.
Record the owner and alert before expiry
Write down which account holds the domain, the DNS host, and how renewal validates (HTTP token, TXT record, or delegated validation). Add an expiry check that fires weeks ahead, not days. Cloudflare issues renewal tokens 30 days before expiry, so a failed HTTP renewal can be caught well before the certificate expires.
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate