certificate status "Validating Ownership" for over 24 hours
ldsjunior-ui
PROOP

21 days ago

Hi Railway team,

Three custom domains on my project have been stuck with a certificate status

"Validating Ownership" for over 24 hours. DNS is correct, and Railway already

detects the records as PROPAGATED, but the Let's Encrypt certificate never

issues, so the domains serve the default *.up.railway.app cert (cert mismatch).

Project: IndustrialPro (id: facaa58c-807b-4d8f-9783-45523d56deb5)

Environment: production

Custom domains (all stuck in VALIDATING_OWNERSHIP):

  • api.industrialpro.com.br -> service "api" (e3ad0aa0-a11f-4777-bb4c-7ea2c48f2d10), expected CNAME aq7nx44h.up.railway.app
  • www.industrialpro.com.br -> service "web" (00189626-1127-4349-bcdc-923fe1a02ccf), expected CNAME 3u0kz0rp.up.railway.app
  • industrialpro.com.br (apex) -> service "web", expected CNAME ow3of1rn.up.railway.app

DNS setup:

  • DNS is on Cloudflare, all records are DNS-only (gray cloud, NOT proxied).
  • All three CNAMEs resolve correctly to the expected targets (verified via dig).
  • Railway shows DNS records status = PROPAGATED for all three.
  • certificateStatus = VALIDATING_OWNERSHIP (stuck 24h+).

Routing is fine (ACME challenge reachable):

Already tried:

  • Removed and re-added the custom domains (CNAME targets regenerated, DNS updated, status back to PROPAGATED).
  • Confirmed DNS-only (no Cloudflare proxy interfering with the challenge).

Still stuck.

Could you please re-trigger / investigate certificate issuance for these three

custom domains? The issuance pipeline appears to be stalled server-side.

Thanks!

Solved$20 Bounty

Pinned Solution

ldsjunior-ui
PROOP

21 days ago

Solved: custom domain stuck on VALIDATING_OWNERSHIP (the missing _railway-verify TXT record)

Posting this in case it helps anyone else. My custom domains sat on VALIDATING_OWNERSHIP for days and never issued a Let's Encrypt cert. The browser kept getting the generic *.up.railway.app certificate, so every branded URL threw a "not secure" error even though the app itself was live on its .up.railway.app URL.

Root cause: each Railway custom domain needs two DNS records, not one:

The traffic CNAME: www.example.com → xxxxxxxx.up.railway.app

An ownership TXT: _railway-verify.www.example.com → railway-verify=

I had only added the CNAME. Without the _railway-verify TXT, Railway never confirms you own the domain, so it never requests the certificate and just sits at VALIDATING_OWNERSHIP indefinitely.

Why it was easy to miss: Railway expects both records, but if you add the CNAME programmatically (or copy only the CNAME), the TXT slips through. If you pull domain status from the public API, note that the verification TXT does not show up in the dnsRecords list (that only returns the CNAME). It lives in separate fields on the domain status: verificationDnsHost (the TXT name, e.g. _railway-verify.www) and verificationToken (the full value, already prefixed with railway-verify=). The dashboard's custom-domain panel shows both records too.

The fix:

Grab the verify TXT for each domain (dashboard, or verificationDnsHost / verificationToken via API).

Add it in your DNS provider, DNS-only / not proxied:

_railway-verify.www.example.com TXT railway-verify=

_railway-verify.api.example.com TXT railway-verify=

Confirm it resolves on your provider's authoritative nameservers (not just a public resolver, which can cache an earlier empty answer for a minute):

dig TXT _railway-verify.www.example.com @

Wait. Railway re-checks DNS on its own cycle. For me, once the TXT was visible, the subdomains flipped verified → ISSUING → VALID within about a minute and served the branded cert automatically.

Bonus, if you're on Cloudflare and your root/apex domain stays stuck even with the TXT in place:

The apex won't validate on Cloudflare DNS-only because Cloudflare flattens the root CNAME into A records, so Railway can't see the apex pointing at it. Trying to force a Railway cert on the apex is a dead end with this setup. What I did instead: redirect the apex to www at Cloudflare's edge, so the apex never needs a Railway cert.

Page Rule: example.com/* → 301 forward to https://www.example.com/$1

Set the apex record to proxied (orange) so Cloudflare's edge serves it. Cloudflare's Universal SSL covers the apex, and the Page Rule returns the redirect before traffic ever reaches the origin.

Keep www and api DNS-only (grey) so Railway serves their own certificates.

End result: www and api get valid Railway/Let's Encrypt certs, and the apex returns a valid 301 to www over HTTPS.

TL;DR: if a custom domain is stuck on VALIDATING_OWNERSHIP, you're almost certainly missing the _railway-verify TXT record (it's separate from the CNAME, and the API hides it outside the dnsRecords list). Add it, wait a minute, done. Apex on Cloudflare is a separate flattening issue, best solved by redirecting apex to www.

3 Replies

Status changed to Open Railway 21 days ago


sheeki03
FREE

21 days ago

I would treat this as certificate issuance, not app routing.

The key symptom is that the hostnames are reaching Railway, but the certificate being served is still for *.up.railway.app. That means the custom-domain route is far enough along for Railway edge to answer, but the custom certificates have not been issued or attached to those hostnames yet.

Before changing anything else, I would verify these four things and then stop cycling the domains:

  1. Keep Cloudflare DNS-only for all three records. Do not proxy them while Railway is validating.
  2. Keep the Railway TXT verification records exactly as shown for each hostname.
  3. Make sure there is no restrictive CAA record on industrialpro.com.br or a parent zone that blocks Let's Encrypt.
  4. For the apex, make sure Cloudflare is flattening the Railway-provided target for ow3of1rn.up.railway.app, not using a manually copied A record.

If those are true, deleting and re-adding the domains was already the right reset. I would not keep doing that now, because each reset can restart validation and create more moving parts.

At that point the clean diagnosis is:

DNS is propagated.
Cloudflare is DNS-only.
The HTTP challenge path is not being redirected away.
Railway edge is answering.
SNI still serves the default `*.up.railway.app` certificate for the custom hostnames.

That points to the certificate issuance or certificate attachment step being stuck, not to the application itself. The next useful action is for Railway to requeue issuance for these three custom domains or refresh the certificate binding on the edge:

api.industrialpro.com.br
www.industrialpro.com.br
industrialpro.com.br

ldsjunior-ui
PROOP

21 days ago

I was able to fix it on my own.


ldsjunior-ui
PROOP

21 days ago

Solved: custom domain stuck on VALIDATING_OWNERSHIP (the missing _railway-verify TXT record)

Posting this in case it helps anyone else. My custom domains sat on VALIDATING_OWNERSHIP for days and never issued a Let's Encrypt cert. The browser kept getting the generic *.up.railway.app certificate, so every branded URL threw a "not secure" error even though the app itself was live on its .up.railway.app URL.

Root cause: each Railway custom domain needs two DNS records, not one:

The traffic CNAME: www.example.com → xxxxxxxx.up.railway.app

An ownership TXT: _railway-verify.www.example.com → railway-verify=

I had only added the CNAME. Without the _railway-verify TXT, Railway never confirms you own the domain, so it never requests the certificate and just sits at VALIDATING_OWNERSHIP indefinitely.

Why it was easy to miss: Railway expects both records, but if you add the CNAME programmatically (or copy only the CNAME), the TXT slips through. If you pull domain status from the public API, note that the verification TXT does not show up in the dnsRecords list (that only returns the CNAME). It lives in separate fields on the domain status: verificationDnsHost (the TXT name, e.g. _railway-verify.www) and verificationToken (the full value, already prefixed with railway-verify=). The dashboard's custom-domain panel shows both records too.

The fix:

Grab the verify TXT for each domain (dashboard, or verificationDnsHost / verificationToken via API).

Add it in your DNS provider, DNS-only / not proxied:

_railway-verify.www.example.com TXT railway-verify=

_railway-verify.api.example.com TXT railway-verify=

Confirm it resolves on your provider's authoritative nameservers (not just a public resolver, which can cache an earlier empty answer for a minute):

dig TXT _railway-verify.www.example.com @

Wait. Railway re-checks DNS on its own cycle. For me, once the TXT was visible, the subdomains flipped verified → ISSUING → VALID within about a minute and served the branded cert automatically.

Bonus, if you're on Cloudflare and your root/apex domain stays stuck even with the TXT in place:

The apex won't validate on Cloudflare DNS-only because Cloudflare flattens the root CNAME into A records, so Railway can't see the apex pointing at it. Trying to force a Railway cert on the apex is a dead end with this setup. What I did instead: redirect the apex to www at Cloudflare's edge, so the apex never needs a Railway cert.

Page Rule: example.com/* → 301 forward to https://www.example.com/$1

Set the apex record to proxied (orange) so Cloudflare's edge serves it. Cloudflare's Universal SSL covers the apex, and the Page Rule returns the redirect before traffic ever reaches the origin.

Keep www and api DNS-only (grey) so Railway serves their own certificates.

End result: www and api get valid Railway/Let's Encrypt certs, and the apex returns a valid 301 to www over HTTPS.

TL;DR: if a custom domain is stuck on VALIDATING_OWNERSHIP, you're almost certainly missing the _railway-verify TXT record (it's separate from the CNAME, and the API hides it outside the dnsRecords list). Add it, wait a minute, done. Apex on Cloudflare is a separate flattening issue, best solved by redirecting apex to www.


Status changed to Solved 0x5b62656e5d 21 days ago


Welcome!

Sign in to your Railway account to join the conversation.

Loading...