On 23 October 2026 a site manager posted the same question to r/DoSEO and r/TechSEO: Google had indexed blog posts under ftp.example.com instead of www.example.com, the developer had removed the FTP subdomain from the server, and the FTP URLs were still in search results. The thread got an answer from John Mueller of Google within fifteen minutes. The case is common. The host can be ftp., staging., dev., a bare server IP or a subdomain left over from an old setup, and the platform does not matter: WordPress, Shopify with a custom domain, a headless frontend or a static site can all end up indexed under the wrong name.
This guide covers what actually controls the cleanup: what the old hostname returns today, which Search Console property can see it, and which Google signals move the main domain back into the index. Every timeline below comes from Google Search Central documentation.
Why Google indexed the site under an ftp or staging subdomain
The original poster did the diagnosis well. URL Inspection showed the FTP URL as indexed, with crawling allowed and a successful fetch. The main-domain twin was “unknown to Google”, with no referring sitemap and no referring page. The detail that explains the rest:
The user-declared canonical pointed to the FTP URL itself. Google-selected canonical was also the FTP URL.
(u/Gullible-Winter294, r/DoSEO, 23 October 2026)
Three conditions produce this. A DNS record such as ftp, staging or a wildcard points at the same server as the live site. The web server answers that hostname with the live site, often because it is the default virtual host. And the site builds its canonical tag from the hostname in the request instead of a configured base URL, so every copy declares itself canonical. Google then has two identical pages, each claiming to be the original, and picks one of them.
How to check what the old subdomain returns now
Before choosing a fix, find out what Google gets when it recrawls. One of the replies made the point that matters most:
First check what an old HTTPS URL actually returns now: DNS failure isn’t a 404.
(u/inevidimka, r/DoSEO, 23 October 2026)
Two commands answer it:
dig +short ftp.example.com
curl -sI https://ftp.example.com/blog/sample-articleIf dig returns nothing, the name no longer resolves. If it returns an IP, curl shows whether you get a 200 with the full page, a 404 or 410, a redirect, or a TLS error because the certificate does not cover that hostname. Run it against several URLs Google actually shows, not only the home page. Google’s DNS and network errors guide uses dig the same way to check A, CNAME and NS records.
“The developer removed the subdomain” can mean any of these states. A deleted virtual host with the DNS record still in place usually means the server’s default site answers, which is the original problem in a new form.
Does a 404 or 410 remove URLs from Google
Yes. Google’s HTTP status code documentation says that URLs already indexed and returning a 4xx code are removed from the index. All 4xx codes except 429 are treated the same, so 404 and 410 behave alike, and crawl frequency for those URLs gradually decreases.
A DNS failure is a different path with a similar end. Google treats DNS errors, timeouts and connection resets like 5xx server errors, and the DNS guide states that “already indexed URLs that are unreachable will be removed from Google’s index within days”. Both routes need a recrawl first, and that is where the waiting comes from. A reply in the thread put a number on it:
Google will deindex once it sees 404 error. Deindex can take upto 3 months
(u/KindlyConnection4420, r/DoSEO, 23 October 2026)
Google publishes no such figure. The removal happens when Google recrawls the URL, and a low-priority URL on a dead host can wait a while for that. Treat three months as one person’s experience, not a rule.
Should you 301 the old subdomain to the main domain
If the same articles live on the main domain, a page-to-page redirect is the better repair. inevidimka suggested keeping the old hostname reachable with valid HTTPS and permanent redirects. John Mueller listed it as the alternative to removal:
Alternatively: Change DNS to point at a site where you can do an all-URL 301 redirect to www, optionally submit a change of address request in Search Console.
(u/johnmu, r/TechSEO, 23 October 2026)
Google’s canonicalization guide ranks redirects as a strong signal that the target should become canonical. A redirect also carries over whatever links point at the wrong host. Three practical conditions:
- The hostname must resolve and serve a certificate valid for it, or the crawler stops at the TLS error before it sees the 301.
- Map each URL to its own counterpart. Sending everything to the home page throws away the page-level signal.
- Keep the redirects. Google’s site move guide says “generally at least 1 year”, and the Change of Address tool asks for at least 180 days when you use it.
The same guide warns that for a medium-sized site it can take “a few weeks or more” for Google to show the new URLs instead of the old ones.
How to verify a deleted subdomain in Search Console
Mueller’s first words were “Verify with DNS”. The Removals tool and URL Inspection only work for URLs in a property you own, and a host that no longer serves files cannot host an HTML verification file. A Domain property is verified with a DNS record (TXT or CNAME) and covers every subdomain and the http, https and ftp protocols. Verify example.com as a Domain property and ftp.example.com, staging.example.com and any forgotten subdomain fall under it, with or without a web server behind them.
The same Domain property also shows the Pages report across all hosts at once, which is the quickest way to find other stray hostnames in the index.
How to remove an entire subdomain with the Removals tool
The Removals tool has a “Remove all URLs with this prefix” option. Enter https://ftp.example.com/ and every URL on that host is hidden. Google’s help page is explicit that this stays on the subdomain: blocking https://staging.domain “will not block www.domain or https://domain.com”. Google’s removal guide says requests take effect within a day.
Four limits from the same page:
- A request lasts about six months. After that the URLs can return if nothing else changed.
- The tool hides results. It does not stop crawling and does not remove anything permanently. The permanent part is a 404 or 410, a password, or noindex.
- If the URL already returns 404 or 502/503 when you file the request, Google assumes the page is gone and lets the request expire.
- Google says not to use it to get the right version of a site indexed, because it can hide all versions of a URL. On a separate subdomain that risk is limited by the prefix rule above. Do not try it on www versus non-www.
So the tool is worth it when the wrong URLs cause damage today: a staging copy with test prices, a dev host with half-built pages, an IP address showing in results. For a duplicate blog on ftp. that will 301 or 404 anyway, Mueller’s last line applies: “If the URLs no long work, they’ll drop out on their own.”
Why robots.txt on the old host makes it worse
Putting Disallow: / on the staging host backfires. Google’s noindex documentation says a page blocked by robots.txt is never fetched, so its noindex rule is never seen, and the page can still appear in results. The canonicalization guide adds that Google may index URLs disallowed in robots.txt without their content. Both Google removal pages list robots.txt as the method not to use. Leave the host crawlable until the 301, 404 or noindex has been read.
Do WordPress, Shopify, Astro or Cloudflare Pages redirect a stray hostname for you
Most platforms protect one duplicate and leave the others to you. What the documentation says for the common stacks:
- WordPress redirects only between www and non-www. The source of
redirect_canonical()carries the comment “Only redirect no-www <=> yes-www”, and for any other host it keeps the requested one. A request to ftp.example.com gets the page, not a redirect. The canonical tag itself comes fromwp_get_canonical_url(), which callsget_permalink()and so follows the Site Address setting. If a WordPress copy declares the ftp host as canonical, look forWP_HOMEorWP_SITEURLbuilt from$_SERVER['HTTP_HOST']inwp-config.php, or a plugin that rewrites the canonical. The “Discourage search engines” checkbox has printed a noindex robots meta tag since WordPress 5.3 instead of addingDisallow: /to robots.txt, per the core development note, and the same note recommends an HTTP header as the most effective way to keep development sites out. - Shopify lets you choose the domain customers see and redirect every other domain to it from the Domains page in the admin. A second domain or subdomain added to the store without that redirect is a duplicate host.
- Cloudflare Pages adds
X-Robots-Tag: noindexto every preview deployment by default. The production<project>.pages.devaddress is a separate host: Cloudflare’s guide to redirecting pages.dev to a custom domain uses a Bulk Redirect with status 301, “Preserve path suffix” and “Subpath matching”, which gives exactly the page-to-page redirect described above. - Astro builds canonical URLs and the sitemap from the
siteoption inastro.config.mjs, so a hard-codedsite: 'https://www.example.com'makes every copy point at production whatever host serves it. - Next.js composes relative metadata URLs, including
alternates.canonical, withmetadataBase, usually set in the root layout. A relative URL withoutmetadataBasefails the build, so the risk is ametadataBaseread from the request or from a preview environment variable.
What the Search Console statuses mean during the cleanup
The Pages report in the Domain property shows both hosts side by side. These statuses come from Google’s Page indexing report documentation and each one tells you something specific about the repair:
| Status | What Google says it means | What it tells you here |
|---|---|---|
| Duplicate, Google chose different canonical than user | Google indexed another URL than the one you declared | Your canonical on www is fine, but Google still prefers the stray host; add the 301 and the sitemap |
| Duplicate without user-selected canonical | The page declares no canonical and Google picked another URL | The template outputs no canonical on this host; fix the base URL |
| Page with redirect | A non-canonical URL that redirects, so it will not be indexed | The 301 on the old host is being read; this is the status you want for every ftp URL |
| Not found (404) | Google will probably keep trying the URL for some time and crawl it less | Normal after deletion; Google says there is no way to make it forget a URL permanently |
| Blocked due to unauthorized request (401) | Googlebot was asked for credentials | Expected on a password-protected staging host |
| Indexed, though blocked by robots.txt | Indexed from links without being crawled | A Disallow is hiding your noindex or 404; remove it |
The same page notes that the live test in URL Inspection follows redirects and tests the final URL without saying so. Test an old ftp URL live and you see the www result, which can look as if the redirect did nothing.
How to get the main domain URLs indexed instead
Removing the wrong host does not by itself index the right one. The poster’s main-domain URLs had no referring sitemap and no referring page, so Google had no reason to fetch them. Fix the signals on the live site:
- Generate the canonical from a configured base URL, so www.example.com pages declare www.example.com whatever hostname served them.
- List the main-domain URLs in the XML sitemap submitted in the live property. Google calls sitemap inclusion a weak signal, and signals stack.
- Check that internal links, hreflang and Open Graph URLs use the main host, not a relative path that inherits the wrong one.
- Run a live test in URL Inspection on a few main-domain URLs and request indexing for the most important ones.
Google’s canonicalization guide says the methods “can stack and thus become more effective when combined”. A redirect from the old host plus a correct canonical on the new one plus the sitemap is the combination to aim for. If the wrong host appeared after a platform change, my migration service and the article on why Google reverts domain migrations cover the redirect map. The Search Console and Indexing API guide explains the Pages report used to track progress.
Which fix fits your case: decision table
| What the old hostname returns | What to do | How long, per Google |
|---|---|---|
| 200 with the same content | 301 each URL to its main-domain twin, fix the canonical base URL | A few weeks or more for a medium site; keep redirects at least 1 year |
| 404 or 410 | Leave it, make sure the main domain is in the sitemap | Removed when recrawled; no fixed time given |
| DNS failure (name does not resolve) | Leave it; delete any CNAME still pointing at a third-party service | Removed within days of the failed crawl |
| TLS error on the old host | Either serve a valid certificate and 301, or remove the DNS record | No Google timeline for TLS failures; without the DNS record it becomes a DNS failure (removed within days) |
| Content that must disappear now (prices, test data) | Domain property via DNS, then Removals with a prefix, plus a permanent fix | Hidden within a day, for about 6 months |
| Old host blocked in robots.txt | Remove the block so Google can see the 404, 301 or noindex | Depends on the next crawl |
How to keep staging and dev hosts out of Google
- Password-protect non-production hosts. Google’s guide to controlling what you share says password protection keeps content out of Search and eventually removes it if it already appears. HTTP basic auth at the server or CDN works on any platform.
- Send
X-Robots-Tag: noindexon every non-production host. The robots meta and X-Robots-Tag specification allows the rule as an HTTP header, so it covers PDFs and images too and survives a theme or template change. Set it in the server or CDN config for the hostname, not in the application, so a database copy from staging to production cannot carry it to the live site. - Remove DNS records when you remove the host. A CNAME pointing at a service you no longer use is the classic subdomain takeover setup: MDN describes an attacker claiming the abandoned name at the provider and publishing their own content on your subdomain.
- Avoid wildcard DNS unless you need it. Cloudflare’s wildcard record documentation explains that
*answers for every name that has no record of its own. Combined with a default virtual host, any typo or invented subdomain serves your live site. - Make the live server reject unknown hostnames. nginx sends a request whose
Hostmatches noserver_nameto the default server for that port, which is the first server block unless one is markeddefault_server, as the request processing guide explains. Apache does the same with the first listed virtual host, per its name-based virtual host documentation. Make that default a dead end:
server {
listen 80 default_server;
listen 443 ssl default_server;
ssl_reject_handshake on; # nginx 1.19.4+, refuses TLS for unknown names
return 444; # closes the connection without a response
}
server {
listen 443 ssl;
server_name staging.example.com;
# ssl_certificate and ssl_certificate_key for this name go here
auth_basic "Staging";
auth_basic_user_file /etc/nginx/.htpasswd;
add_header X-Robots-Tag "noindex" always;
}The always flag matters. The headers module documentation says add_header only applies to 200, 201, 204, 206, 301, 302, 303, 304, 307 and 308 responses unless always is set, so without it the 401 from basic auth goes out without the noindex header. ssl_reject_handshake needs nginx 1.19.4 or later, and code 444 is nginx’s non-standard way to close the connection.
My staging workflow guide shows the server configuration for basic auth and the noindex header. A website check includes a sweep of DNS records and indexed hostnames, and a maintenance plan keeps that list current after every server or agency change.







