Heroku custom domain solution

Redirect Your Apex Domain to Your Heroku App

Heroku only accepts CNAME records for custom domains, but DNS standards forbid CNAME at the apex. The fix: point www at Heroku, then redirect your naked domain to www with two DNS records.

Get Started — Free
TL;DR

Heroku only allows CNAME records for custom domains, but apex domains (yourdomain.com without www) can't use CNAME per RFC 1034. The fix: point www to your Heroku app via CNAME, then redirect the apex to www using ApexToWWW. Two DNS records, free, automatic SSL.

The Heroku Apex Domain Problem

When you add a custom domain to a Heroku app, Heroku gives you a DNS target that looks something like shielded-meadow-12345.herokudns.com or mydomain-abc123.herokudns.com. You're expected to point your domain at that target with a CNAME record. This works perfectly for subdomains like www.example.com, app.example.com, or api.example.com.

But it fails at the apex domain — also called the root domain, naked domain, or bare domain. That's the version without any subdomain prefix: example.com instead of www.example.com.

Why CNAME doesn't work at the apex

RFC 1034 section 3.6.2 states that a CNAME record cannot coexist with any other record type at the same DNS name. The apex of every domain must have NS records (pointing to the authoritative nameservers) and an SOA record. Because those records are mandatory, you cannot legally place a CNAME at the apex. Most DNS providers will simply refuse to save the configuration.

So when Heroku tells you to "create a CNAME pointing to your-app-12345.herokudns.com", you can do that for www but not for the bare example.com. Heroku does not publish a static IP address for your custom domain either, so you can't fall back to an A record pointing at Heroku.

Common errors users see

  • "This site can't be reached" when typing example.com in the browser — there's simply no DNS record at the apex.
  • "DNS_PROBE_FINISHED_NXDOMAIN" for the naked domain.
  • The apex resolves to your registrar's parking page instead of your Heroku app.
  • Cloudflare's CNAME flattening seems to "work" but breaks during outages, region failover, or when Heroku rotates IPs.
  • Heroku ACM fails to issue a certificate for the apex because the domain doesn't actually point at Heroku.

The Solution: Point WWW at Heroku, Apex at ApexToWWW

The clean fix is a two-part DNS setup. Your www subdomain points at your Heroku app via CNAME (which Heroku fully supports). Your apex domain points at ApexToWWW, which serves a 301 redirect to www. No nameserver changes, no CNAME flattening tricks, no DNS provider lock-in.

Step 1: Add your www subdomain to Heroku

From your project directory, run:

heroku domains:add www.example.com

Heroku will print the DNS target you need:

Adding www.example.com to ⬢ your-app... done
 ▸    Configure your app's DNS provider to point to the DNS Target
 ▸    shielded-meadow-12345.herokudns.com

You can also add the domain from the Heroku dashboard under Settings → Domains → Add domain. Either way, copy the herokudns.com target — you'll need it in the next step.

Step 2: Create a CNAME record for www

At your DNS provider, add a CNAME record:

  • Type: CNAME
  • Name / Host: www
  • Value / Target: shielded-meadow-12345.herokudns.com (your actual Heroku DNS target)
  • TTL: 300 or Auto

Step 3: Add an A record for the apex

Now create an A record for the apex (host @) pointing to ApexToWWW's IPv4 address:

  • Type: A
  • Name / Host: @
  • Value: 65.21.184.101

Step 4: Add an AAAA record for the apex

And the matching IPv6 record:

  • Type: AAAA
  • Name / Host: @
  • Value: 2a01:4f9:c012:a304::1

Step 5: Verify with curl

Wait 5 to 30 minutes for DNS to propagate, then test:

curl -I https://yourdomain.com

HTTP/1.1 301 Moved Permanently
Location: https://www.yourdomain.com/

You should also see your Heroku app respond on the www version:

curl -I https://www.yourdomain.com
# HTTP/1.1 200 OK (or whatever your Heroku app returns)

DNS records summary

Here are all three records you need at your DNS provider, in one table:

DNS Records for a Heroku Custom Domain Setup

Type Name / Host Value / Points To Purpose
CNAME www your-app-12345.herokudns.com Routes www to Heroku
A @ 65.21.184.101 Apex IPv4 → redirect
AAAA @ 2a01:4f9:c012:a304::1 Apex IPv6 → redirect

Why Not Just Use Heroku's A Records?

This is the most common question developers ask: "Why doesn't Heroku just publish A records I can use at the apex?"

The short answer: Heroku doesn't publish static A records for custom domains. Heroku's routing layer runs on AWS, and the underlying IP addresses change as the platform scales, fails over between availability zones, and rotates load balancers. If you hardcoded an IP at the apex, your site would eventually break without warning.

Some DNS providers offer ALIAS or ANAME records — vendor extensions that resolve a CNAME-like target server-side and return the result as A/AAAA records to clients. Providers that support this for Heroku include:

  • DNSimple (ALIAS records)
  • DNS Made Easy (ANAME records)
  • easyDNS (ANAME records)
  • Cloudflare (CNAME flattening at the apex, but only if Cloudflare is your authoritative DNS)
  • Route 53 (alias records, but only for AWS resources — not Heroku)

If you happen to use one of those providers, ALIAS/ANAME records are a valid alternative. But they lock you into a specific DNS vendor, add an extra resolution hop on every request, and don't work with the majority of registrars (GoDaddy, Namecheap, Google Domains, Porkbun, and most resellers all lack ALIAS support).

ApexToWWW works with any DNS provider because it only needs plain A and AAAA records — the most basic record types in DNS, supported universally. Your apex resolves to a fixed pair of IPs that we maintain, and we serve the 301 redirect.

Works With Other Platforms Too

The same setup works for any host that requires (or recommends) a www subdomain. If you're considering moving off Heroku or running a multi-cloud setup, ApexToWWW handles the apex redirect identically across providers:

Frequently Asked Questions

Does this work with Heroku's automated certificate management (ACM)?

Yes. Heroku ACM provisions a TLS certificate for your www subdomain automatically. ApexToWWW provisions its own Let's Encrypt certificate for the apex. The two operate independently, so visitors who hit example.com get a secure HTTPS 301 redirect from us, and the actual page is served over HTTPS by Heroku. You don't have to upload, manage, or renew certificates anywhere.

Do I need to change my nameservers?

No. Keep using whatever DNS provider you already have — GoDaddy, Namecheap, Cloudflare, Google Domains, Porkbun, AWS Route 53, or anything else. You only need to add three records (a www CNAME and two apex records). There are no nameserver changes and no proxy in front of your traffic.

What about the Heroku SNI endpoint?

Heroku uses SNI (Server Name Indication) for SSL on all custom domains by default, including paid SNI endpoints on legacy plans. Your www CNAME points directly at the Heroku DNS target, so SNI works exactly as Heroku expects. ApexToWWW handles SNI on its own end for the apex — we look at the SNI hostname in the TLS handshake to serve the right Let's Encrypt certificate before issuing the redirect.

Will it work with Heroku Enterprise or Private Spaces?

Yes. Heroku Enterprise, Shield Private Spaces, and standard Private Spaces all use herokudns.com CNAME targets for custom domains. The setup is identical: www CNAME to your Private Space DNS target, then an A and AAAA record on the apex pointing at ApexToWWW.

Fix Your Heroku Apex Domain in 2 Minutes

No signup, no credit card, no nameserver changes. Add three DNS records and your naked domain redirects cleanly to your Heroku app.

Set Up Your Redirect — Free