> ## Documentation Index
> Fetch the complete documentation index at: https://cloud.laravel.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Domain Verification

> Learn how to add, validate, and verify custom domains on Laravel Cloud.

When you add a custom domain to Laravel Cloud, it needs to confirm that you own the domain and that your DNS records are set up correctly. This process is called verification. Occasionally, verification may appear stuck or time out entirely — usually because a DNS record is misconfigured or has not finished propagating (the process by which DNS changes spread across the internet).

## Quick checklist

* Confirm you are updating DNS at the provider that is actually responsible for your domain. This is not always your registrar — for example, if you moved your nameservers to Cloudflare, your records need to be added in Cloudflare, not at your registrar.
* Confirm you added **all** records Laravel Cloud shows, including `www` and wildcard records if they are enabled.
* Confirm record **names** and **values** match exactly what Laravel Cloud shows — even small differences (extra dots, missing prefixes) will cause verification to fail.
* If you are using Cloudflare DNS, review the proxy status (orange cloud vs. grey cloud) for each record. Some records, such as SSL validation records, must not be proxied.

## Before you start

Before adding any records, confirm which provider is actually serving DNS for your domain — this is not always where you purchased it. For example, if you registered at GoDaddy but pointed your nameservers to Cloudflare, you must add records in Cloudflare. Run the following command to check:

```bash theme={null}
dig NS example.com +short
```

The output will list nameserver hostnames (e.g., `anna.ns.cloudflare.com`). Add your Laravel Cloud records at the provider that owns those nameservers.

## Add your DNS records

### General rule of thumb

Most DNS providers have a "host" or "name" field that expects only the subdomain portion of a record name — not the full domain. Your provider appends the domain automatically:

* For `www.example.com`, enter `www`
* For `_cf-custom-hostname.example.com`, enter `_cf-custom-hostname`
* For `_acme-challenge.example.com`, enter `_acme-challenge`
* For `example.com` itself, most providers use `@` or leave the host blank

After saving a record, always re-open it in your provider's dashboard and confirm the assembled name matches exactly what Laravel Cloud shows. This is the most effective way to catch formatting mistakes early.

### Provider-specific instructions

<AccordionGroup>
  <Accordion title="Cloudflare">
    If the `dig NS` output lists Cloudflare nameservers (e.g., `anna.ns.cloudflare.com`), add your records in Cloudflare's DNS dashboard.

    <Steps>
      <Step title="Open your domain in Cloudflare">
        In Cloudflare, select your website and open **DNS**.
      </Step>

      <Step title="Add the origin record(s) from Laravel Cloud">
        In Laravel Cloud, open your domain's configuration and copy the **origin** record(s). These records tell Cloudflare where to send traffic for your domain.

        For the record name in Cloudflare:

        * Use `@` for the root domain (e.g., `example.com`)
        * Use `www` for `www.example.com`
        * Use `*` for `*.example.com` (wildcards), if shown

        For proxy status (the orange / grey cloud icon in Cloudflare):

        * Origin records are typically safe to proxy (orange cloud) if you selected a Cloudflare proxy option in Laravel Cloud.
        * If you are unsure, start with the proxy status Laravel Cloud recommends in the UI.
      </Step>

      <Step title="Add the pre-verification TXT record (if shown)">
        If Laravel Cloud shows an ownership verification record like `_cf-custom-hostname.example.com`, add it as a **TXT** record. Set the record name to `_cf-custom-hostname` — Cloudflare appends the domain automatically.
      </Step>

      <Step title="Add SSL validation records (if shown)">
        Laravel Cloud may show `_acme-challenge` records used to issue your domain's SSL certificate. Copy them exactly as shown.

        If the `_acme-challenge` record is a **CNAME**, ensure it is set to **DNS only** (grey cloud) in Cloudflare. Proxying this record will prevent the SSL certificate from being issued.
      </Step>
    </Steps>

    **Wildcard domains and DCV delegation**

    Wildcard domains (e.g., `*.example.com`) require a special `_acme-challenge` CNAME called a DCV delegation record. This allows Laravel Cloud to automatically issue and renew SSL certificates for your wildcard domain. Keep this record in place and ensure it remains **DNS only** (grey cloud) at all times — removing or proxying it will prevent certificate renewals.

    **Troubleshooting Cloudflare records**

    * Confirm you are editing DNS records in the correct Cloudflare account and zone.
    * Confirm record names are not duplicated. A common mistake is entering the full name including the domain, which causes Cloudflare to append it again (e.g., `_cf-custom-hostname.example.com.example.com`).
    * If you are pre-verifying your domain and see Cloudflare-related verification errors, temporarily setting the record to **DNS only** may be required until verification completes. You can re-enable the proxy afterward.
  </Accordion>

  <Accordion title="Amazon Route 53">
    Unlike most providers, Route 53 accepts fully qualified record names — you can paste the complete name from Laravel Cloud (e.g., `_cf-custom-hostname.example.com`) directly into the name field. Route 53 may add a trailing dot (e.g., `_cf-custom-hostname.example.com.`), which is standard DNS formatting and is expected.

    If you are not sure you are editing the correct hosted zone, confirm which nameservers are authoritative for your domain:

    ```bash theme={null}
    dig NS example.com +short
    ```

    The output should match the nameservers listed in your Route 53 hosted zone.
  </Accordion>

  <Accordion title="GoDaddy">
    GoDaddy's DNS editor uses a "Host" field that expects only the subdomain portion. For example, if Laravel Cloud shows `_cf-custom-hostname.example.com`, enter `_cf-custom-hostname` — GoDaddy adds `.example.com` for you.

    After saving, GoDaddy displays the full record name. Confirm it matches the record name shown in Laravel Cloud exactly, with no repeated or missing parts.
  </Accordion>

  <Accordion title="Namecheap">
    Namecheap's DNS editor uses a "Host" field that expects only the subdomain portion. For example, if Laravel Cloud shows `_acme-challenge.example.com`, enter `_acme-challenge` — Namecheap adds the domain automatically.

    For root-domain records (i.e., records for `example.com` itself), use `@` as the host value.
  </Accordion>

  <Accordion title="Squarespace / Google Domains">
    Squarespace (which acquired Google Domains) has its own naming conventions. In any name or host field, omit the `.example.com` suffix — Squarespace appends it for you:

    * If Laravel Cloud shows `_cf-custom-hostname.example.com`, enter `_cf-custom-hostname`
    * For `www.example.com`, enter `www`
    * For a wildcard `*.example.com`, enter `*`
  </Accordion>
</AccordionGroup>

## Verification timeline

Most domains verify within 15 minutes once the correct DNS records are publicly visible. However, propagation can take longer depending on your DNS provider and the record's TTL (time-to-live) — a value that controls how long DNS results are cached before being refreshed.

Laravel Cloud will automatically retry verification checks for approximately 12 hours. If verification still cannot complete after that period, the domain will time out and you may need to correct your DNS records and retry.

## Check your records in the terminal

You can verify that your DNS records are publicly visible by running `dig` commands in your terminal. Replace `example.com` with your actual domain:

```bash theme={null}
# Which DNS provider is responsible for your domain?
dig NS example.com +short

# Are your origin records (the records that point traffic to Laravel Cloud) resolving?
dig A example.com +short
dig CNAME example.com +short

# Is the ownership verification record visible?
dig TXT _cf-custom-hostname.example.com +short

# Are the SSL validation records visible? (may be TXT or CNAME depending on your setup)
dig TXT _acme-challenge.example.com +short
dig CNAME _acme-challenge.example.com +short
```

If any command returns no output, that record is either missing or has not finished propagating.

## Common verification issues

### Records added in the wrong place

If your domain is managed in multiple places (for example, you registered at GoDaddy but pointed your nameservers to Cloudflare), it is easy to add records in the wrong place. Records must be added at the provider that is actually serving your DNS — not necessarily where you purchased the domain. Run `dig NS example.com +short` to confirm which provider is authoritative.

### Missing `www` records when redirects are enabled

Laravel Cloud's `Redirect from www.` setting is enabled by default and is the recommended configuration. When enabled, Laravel Cloud will validate both `example.com` and `www.example.com`, which means DNS records are required for both hostnames.

If you only added records for `example.com` and skipped `www`, verification can fail. Make sure you added records for both hostnames exactly as shown in the domain configuration screen.

### DNS provider formatting issues (host vs. full name)

Most DNS providers have a "host" or "name" field that expects only the subdomain portion of a record name. The provider then appends your domain automatically. If you paste the full name from Laravel Cloud into this field, the domain gets added twice. For example:

* `_cf-custom-hostname.example.com.example.com` — incorrect, domain appended twice
* `_cf-custom-hostname.example.com` — correct

To avoid this, enter only the part before your domain (e.g., `_cf-custom-hostname`). After saving, re-open the record to confirm the assembled name matches what Laravel Cloud shows. See the [provider-specific instructions](#provider-specific-instructions) above for details.

### Cloudflare proxy and DNS-only records

Cloudflare has a proxy feature (shown as an orange cloud icon) that routes traffic through its network. While this is useful for your site's origin records, certain verification and SSL records must bypass the proxy and be set to **DNS only** (grey cloud). In particular, `_acme-challenge` records used for SSL certificate issuance and DCV delegation must always be DNS only — proxying them will prevent certificates from being issued or renewed.

If you are pre-verifying your domain and see Cloudflare-related verification errors, temporarily setting the hostname's record to **DNS only** may be required until verification completes. You can re-enable the proxy afterward.

### Verification appears propagated but Laravel Cloud still shows "Validating"

If your records look correct when checked with `dig` or an external DNS tool, but the domain is still showing as "Validating" or "Timed Out" in Laravel Cloud, this may indicate that our network provider (Cloudflare) has flagged the domain for manual review. This can happen even if your domain is not hosted on Cloudflare, because Laravel Cloud uses Cloudflare's infrastructure behind the scenes to manage SSL certificates and routing.

Cloudflare's automated systems occasionally flag domains due to potential abuse concerns. This is sometimes a false positive and requires intervention on the Cloudflare side to resolve. If you believe this is affecting your domain, please raise a ticket through the **Help** portal in your Laravel Cloud dashboard so the team can assist.

## When to contact support

If your domain is still stuck after working through the steps above, contact support through the **Help** portal in your Laravel Cloud dashboard. To help the team diagnose the issue quickly, include:

* Your domain name
* Screenshots of the DNS records as they appear in your DNS provider's dashboard
* The output from the `dig` commands listed in the [Check your records in the terminal](#check-your-records-in-the-terminal) section above
