Domain and DNS Setup for Self-Hosted n8n
I’ve migrated self-hosted n8n instances between VPS providers, and DNS was the one “small” detail that caused the most confusing webhook failures.
Domain and DNS Setup for Self-Hosted n8n is how you make your editor URL, webhooks, and HTTPS behave predictably in production.
Pick the domain pattern that won’t fight your reverse proxy later
Use a dedicated subdomain for n8n, not your root domain. In practice, n8n.yourdomain.com is cleaner than yourdomain.com/n8n because most reverse proxies, TLS certificates, and webhook providers behave more consistently with a host-based route.
If you already use the root domain for marketing pages, keep it that way and reserve a subdomain for your automation stack. This also makes it easier to rotate infrastructure without touching the rest of your site.
Choose the DNS record type based on how you host n8n
Your DNS choice depends on what sits at the public edge:
- VPS with a public IPv4: use an A record for n8n pointing to your server IP.
- VPS with IPv6 enabled: add an AAAA record too, but only if your reverse proxy is actually listening on IPv6.
- Load balancer or managed edge: use a CNAME (or an AWS Alias) pointing to the load balancer DNS name instead of hardcoding IPs.
If you’re using AWS Route 53 and targeting an AWS resource, Alias records are designed to track target changes automatically, which avoids surprise outages when IPs rotate. AWS Route 53: choosing alias vs non-alias records
Cloudflare vs Route 53 vs Cloud DNS: a practical comparison
| Provider | What it’s great at for n8n | Real downside you’ll hit | How to work around it |
|---|---|---|---|
| Cloudflare DNS | Fast global DNS, easy record management, optional proxy/WAF for protecting your origin | Proxy mode only applies to A/AAAA/CNAME for HTTP(S), and proxying the wrong targets can break connectivity | Keep n8n record proxied only if you’re serving HTTPS through Cloudflare; otherwise set “DNS only” for non-standard needs |
| AWS Route 53 | Rock-solid DNS, Alias support for apex and AWS resources, clean integration with ELB/NLB | More knobs than most people need; mis-pointing to the wrong target type is common during migrations | Prefer Alias to AWS resources and treat record changes like deployments (plan, apply, verify) |
| Google Cloud DNS | Simple hosted zones, reliable propagation, integrates cleanly if your n8n runs on GCP | Fewer “guardrails” in the UI, so it’s easy to ship a record that looks right but points to the wrong edge | Always verify with dig + an HTTPS header check after every DNS change |
Cloudflare proxy setting: when “orange cloud” helps and when it hurts
If you use Cloudflare, you’ll choose between “proxied” and “DNS only.” Cloudflare’s proxy is intended for web traffic and only applies to A/AAAA/CNAME records used for HTTP(S). Cloudflare DNS proxy status
Common mistake: proxying a record that isn’t supposed to be proxied (or proxying during debugging), then chasing phantom issues at the reverse proxy layer.
Fix: If you’re troubleshooting, temporarily switch the n8n record to “DNS only” so you can confirm your origin and reverse proxy work directly. Once stable, enable proxy mode if you want Cloudflare’s edge protection and you know your reverse proxy + TLS setup is correct.
TTL and propagation: reduce risk during migrations
When you’re about to migrate servers, lower your DNS TTL ahead of time so changes propagate faster. After the migration is stable, you can increase TTL again to reduce resolver churn.
Common mistake: changing IPs and immediately testing from the same network/device. Your resolver may be caching the old answer even if the authoritative DNS is correct.
Make n8n generate the right public URLs behind a reverse proxy
Most “my webhook URL shows localhost” problems aren’t DNS—they’re n8n building a URL from internal values that don’t match what the public internet sees.
n8n constructs webhook URLs using N8N_PROTOCOL, N8N_HOST, and N8N_PORT. When you place n8n behind a reverse proxy (internal 5678, public 443), set WEBHOOK_URL so n8n registers and displays the correct public URL, and set N8N_PROXY_HOPS appropriately. n8n: configure webhook URLs with reverse proxy
N8N_PROTOCOL=httpsN8N_HOST=n8n.yourdomain.com N8N_PORT=5678 WEBHOOK_URL=https://n8n.yourdomain.com/N8N_PROXY_HOPS=1
Common mistake: setting the DNS record correctly but leaving WEBHOOK_URL unset, then wondering why external services keep calling the wrong endpoint.
Fix: Treat WEBHOOK_URL as mandatory for production when a reverse proxy terminates TLS, then re-test every integration that registers webhooks (Stripe, GitHub, Slack, etc.).
HTTPS readiness: DNS is only half the story
DNS only points traffic at your edge. You still need TLS termination and correct forwarding headers so n8n sees the original host/protocol. n8n recommends using a reverse proxy for SSL/TLS in self-hosted deployments. n8n: set up SSL
Common mistake: the browser shows HTTPS, but the reverse proxy doesn’t forward the expected headers, so n8n behaves like it’s behind HTTP and generates mixed URLs.
Fix: Ensure your last proxy in the chain forwards the standard “forwarded” headers consistently and keep proxy hops aligned with your network path.
How to verify DNS and HTTPS the way production traffic sees it
Don’t rely on a single “it loads in my browser” check. Verify DNS answers, then verify HTTPS and headers.
dig +short n8n.yourdomain.com Adig +short n8n.yourdomain.com AAAAnslookup n8n.yourdomain.com
curl -I https://n8n.yourdomain.com/
If DNS resolves correctly but curl fails, your issue is no longer DNS—it’s firewall rules, reverse proxy routing, TLS config, or the upstream port mapping.
Hardening tip that prevents “origin IP leaks” during growth
If you use an edge proxy (like Cloudflare) and you want real protection, avoid leaving an alternate DNS record that points directly to your origin IP. That “backup” record often becomes the easiest way attackers bypass your edge. If you truly need a backdoor for admin access, keep it locked to a private VPN or an allowlisted IP range at the firewall.
Common DNS mistakes that break n8n in real life
- Wrong record name: creating an A record for @ instead of n8n, then wondering why the subdomain doesn’t resolve.
- Conflicting records: having both A and CNAME for the same hostname in different places (common after transfers).
- IPv6 mismatch: publishing AAAA while your reverse proxy only listens on IPv4.
- Proxy toggle whiplash: switching between proxied/DNS-only without re-validating TLS and webhook URLs.
FAQ: advanced questions that come up after your first deployment
Should you use the root domain or a subdomain for n8n?
Use a subdomain in most production setups. You’ll avoid path-based edge cases, simplify certificate management, and keep future migrations cleaner.
Can you run n8n on an apex (root) domain with a load balancer?
You can, but it’s easier when your DNS provider supports apex-friendly targets (like Route 53 Alias). If you’re not using an apex-safe record type, you’ll end up fighting limitations that subdomains avoid entirely.
What DNS record do you use when your server IP changes often?
Avoid hardcoding IPs. Point a CNAME to the stable DNS name of your load balancer or edge, or use Alias-style records where available so the DNS target stays valid as infrastructure changes.
Why does n8n still show localhost or an internal URL even after DNS is correct?
Because DNS doesn’t control what n8n prints or registers as a webhook URL. Set WEBHOOK_URL (and align N8N_PROTOCOL/N8N_HOST) so n8n uses the public-facing address when it builds links and registers webhooks.
Do you need to change anything after enabling HTTPS at the proxy?
Yes—verify that the public URL is HTTPS everywhere (editor access + webhooks) and ensure your n8n URL variables match. If you switch from HTTP to HTTPS but keep an old webhook URL registered in a third-party service, triggers may silently stop.
What’s the fastest way to confirm the issue is DNS vs reverse proxy?
Run dig (DNS resolution) and curl -I (HTTPS response). If dig returns the expected IP/target but curl fails, focus on firewall, proxy routing, certificates, and upstream connectivity—not DNS.
Final checklist you can run every time you change DNS
- Create/verify A (and optionally AAAA) or CNAME/Alias for n8n.
- Confirm DNS answers with dig from at least one network outside your server.
- Confirm HTTPS response with curl -I.
- Set WEBHOOK_URL and align N8N_PROTOCOL/N8N_HOST so n8n generates correct public URLs.
- Re-test at least one real webhook integration after changes.
Once your domain, DNS, and URL variables are stable, n8n stops feeling “fragile” and starts behaving like a proper production service you can evolve without breaking automations.

