Transferring a Domain from Google Domains to Cloudflare

To no one’s surprise, Google has killed yet another popular service.  To the dismay of many, that service was Google Domains; see  Google Domains was popular because it was inexpensive, simple to manage, no-frills, no-BS.  Google Domains did not charge extra for private WHOIS, which kept us from getting offers to submit our domain to over 300 search engines, or fake “renewal” scams.  This made it great for all those projects “I’ll get to one day”.  No communication was sent by either Google or Squarespace, everyone found out via news stories.  The news broke on June 15, I registered domains on June 12 and there was no indication of a sale.  Since Squarespace’s prices are almost 2x what Google Domains charges, and its business model is selling website builders, this has left a lot of people looking for a good alternative.  Cloudflare gets mentioned because of its price and trust in the technical community.


Since a few of my domains are actually live and pointing to things being used, the prospect of switching a registrar brings a little nervousness.  It’s just DNS, nothing ever happens because of that…  Fortunately, I have a few domains for projects I’ll get to one day, so I can test with those.

I recommend doing this with two browser windows open, one for Cloudflare and one for Google Domains, since there is a little back-and-forth.

Step 0: Prechecks!  Can you transfer your domain?  Do you have a Cloudflare account?

The first thing to note is, you can’t transfer a domain within 60 days of registration (this is an ICANN rule).  Also, your registration needs to be more than 15 days from expiration, so start the process before then or you’ll need to renew, then transfer.  Cloudflare also does not support all the extensions Google does, notably .dev (although they are working in supporting .dev, and should be ready by the end of the summer).  I did not check .zip.

You’ll need a Cloudflare account.  If you don’t have one, create an account and make sure you do the email verification.  You can’t transfer a domain to Cloudflare until you have verified your email.  This took me less than 5 minutes overall.

As part of the process, you need to change your nameservers to Cloudflare.  This involves DNS propagation and make take up to 24 hours.  I have a couple side things on shared hosting, and am using their nameservers, so this is the part which worries me the most.  If you’re using a shared host’s nameservers, check their documentation before switching anything, to make sure you don’t need some extra configuration in the host’s setup also.

Cloudflare’s documentation for transferring is at

Several of my domains are used only to forward traffic to a far less glamorous URL, usually a registration site for an event, which I have to change 3-4 times per year.  Cloudflare does support URL forwarding, not as elegantly as Google Domains. You can set this up after my Step 2 below.  Cloudflare’s documentation is at  That being said, I’d do a transfer between events when the forwarding URL isn’t being used.

Step 1: Unlocking Domains in Google Domains

Log into Google Domains, select the domain you want to transfer, click on Registration Settings, then scroll down to the Domain Registration section.  By default, Google locked domains from being transferred, so you need to unlock it.  In a future step you’ll need a transfer code, this is also where you find that.


Step 2: Transfer DNS to Cloudflare

Before you transfer the domain registration, you first transfer DNS to Cloudflare.  Log into your account, and on the Websites page, click one of the “Add site” buttons.  This will start the setup process.


The first step is to choose the DNS plan we want to use.  I love places that have free plans for all my hobby projects, so that’s what I’m starting with.


IMPORTANT!!  Cloudflare then scans your domain’s DNS entries and gives you an opportunity to confirm them.  It’s a good idea to compare the imported records to your configuration.  You can also add records, so this is a good time to add a DKIM since GMail is starting to check those (see


As I said above, this is where you actually transfer DNS to Cloudflare’s nameservers.  If you’re on a shared host, double check if you need any additional configuration in your website host when using external nameservers.  Bare minimum you’ll need to visit your host to switch the nameserver list.


If you’re using your domain to forward traffic to another URL, you can now set up the forwarding in Cloudflare to hopefully avoid traffic interruptions.  Cloudflare’s documentation is at

Step 3: Switch Nameservers

If you’re using Google’s nameservers, go back to Google Domains and visit the DNS page.  There is an almost invisible set of tabs at the top of the page, you need to click “Custom name servers”.


Add the nameservers Cloudflare told you to use, and click the “Switch to these settings” link in the yellow alert bar.


Once you see this, you’re done.


Google’s documentation for this process is at

Every shared host has a different control panel, so you’re kind of on your own for this part.  Look up their docs.

Step 4: Turn Off DNSSEC

Regardless of whose nameservers you’re using, you need to turn off DNSSEC.  This is back in Google Domains, on the DNS page.


Click “Unpublish records” and you’re done with that.


Step 5: Check Nameservers (and wait, probably)

Go back to Cloudflare and click the “Check nameservers” button, and wait for the confirmation email.  Despite the note that it may take a few hours, it only took about 10 minutes.


Step 6: While You Wait, Check Payment Info

While we’re waiting, check your payment information.  If you set up a new account (like I did), you need to have a valid credit card on file in order to transfer a domain.  There is a transfer fee, but this also adds a year to your registration (with some exceptions, read the page).


Step 7: Initiate Transfer

After you receive your confirmation email that the nameservers have been updated, log back in to Google Domains and Cloudflare.  In Cloudflare, go to Domain Registration >> Transfer Domains, and select the domain you want to transfer, then click Confirm Domains.


Go back to Google Domains, and perform the following steps:

If you did not unlock the domain earlier, go to Registration Settings and turn off the domain lock.


Get the auth code.  You’ll have to re-authenticate to Google, and the code will be in a popup window. 


Copy the transfer code and paste it into the box in Cloudflare.


Add your registration details, and click the “Confirm and Finalize Transfer” button.  These might be auto-filled if you turned off Privacy Protection, but I wasn’t going to risk exposing my contact information to  DNS harvester bot.


In addition to the confirmation page, Cloudflare will send you an email confirming your intent and that you have been charged.


Within a few minutes, Google Domains will send an email for you to approve the transfer.  Click that button to open a pop-up in Google Domains, then click the Transfer link.



A few minutes later, you’ll get an email from Cloudflare confirming the transfer is complete.


Step 8: Turn DNSSEC Back On

In Cloudflare, choose your domain from the list of Websites, then go to DNS >> Settings, and click the Enable DNSSEC button.

Side Project Chronicles, ep. 4: CLI/SDK


This post got a little long, so here are the learnings:

  1. Any of the AWS SDKs, including boto3, as well as commercial IaC, all have Lightsail libraries.
  2. The user id and user secret created in Lightsail do not have console access, so to use an SDK you need to create a user via the regular IAM.
  3. Lightsail libraries in SDKs are limited to only the functionality of the Lightsail console.
  4. Lightsail S3 buckets do not appear in the ListBuckets results from regular S3 components in the SDKs, but can be addressed directly using a regular S3 library if you know the bucket name.
  5. When using a regular S3 library, the functionality is again limited to what Lightsail supports; attempting an unsupported action returns “Access Denied” exception.
  6. The async .NET SDKs for .NET 5+ do not implement all the methods found in the full .NET Framework versions.  I switched to boto3 and Python rather than install .NET 4.x to test ListBuckets and similar actions; see #4 for how that worked out.

The Full Adventure

The Lightsail console provides us a lot of functionality, but it’s not easy to audit the changes we make using the console.  The console is a manual process and we have to remember to always check the same settings; hence why IaC is a best practice.  Based on our look at the S3 bucket, we know more is happening via Lightsail than we can see, and we assume good decisions are being made.  Something specific I’d like to check is if objects are encrypted at rest.  Since a lot of automated compliance tooling uses the API or and SDK to check adherence to enterprise rules, we want to make sure we can use these to access the settings we’re interested in.  As it turns out we have a number of options for SDK/CLI/IaC for Lightsail:

(SDKs are also available for several languages other than .NET)

I want to try the AWS SDK for .NET, since that’s my most native programming language.  The AWS SDK specifically for Lightsail is available via Nuget, which describes Lightsail as “[a]n extremely simplified VM creation and management service.”  Despite that outdated description, the SDK is current.

The Lightsail S3 buckets were not visible in the usual S3 console, so I wanted to see if they are visible to the CLI or SDK.  AWS has an example of how to list buckets with the SDK, at

As it turns out, the bucket access keys we created in the Lightsail console do not grant permissions to use CLI/SDK.  This is one instance where we need to use the normal AWS control panel rather than the Lightsail control panel, and create an IAM user with more privileged  permissions (

With a more privileged set of user credentials in place, we can run the AWS sample, and see that the Lightsail buckets are not listed in the response.  That makes sense, since we didn’t see them in the API, but it’s good to check.

If we know the name of the bucket, we can access it directly, but the actions we can perform are limited.  It was at this point I realized not all functions in the .NET Framework version have been implemented in the .NET version; instead of installing .NET 4.x, I switched to python boto3.  What I found is, when using a regular S3 library, the you can list_objects but not get_bucket_encryption.  Get_bucket_encryption returns an Access Denied error, even when using secrets for the root user.

To wrap this all up, you can use either a Lightsail SDK, or a regular S3 SDK, to work with Lightsail buckets.  Either way, functionality is limited to what Lightsail supports.  You’ll just have to take it on faith that AWS’ defaults are secure enough for your needs.  It’s unlikely policy scanning tools can detect or validate best practices on your Lightsail buckets.