The short answer
Google Cloud takes two PEM files: the server certificate followed by its intermediates in one file, and an unencrypted private key in another. Create a certificate from them with gcloud compute ssl-certificates create or gcloud certificate-manager certificates create, then attach it to the target HTTPS proxy in front of your load balancer. The detail that decides everything afterwards is which of the three certificate systems you land in: a target proxy holds 15 Compute Engine certificates or 100 Certificate Manager certificates, and if a certificate map is attached as well, the map is used and the directly attached certificates are ignored. Since March 15, 2026 a public TLS certificate may not exceed 200 days, so a certificate you supply comes back around twice a year.
Three systems, one load balancer
Google Cloud has three separate ways to put a certificate on a load balancer, and they are not layers of one system. The oldest is the Compute Engine SSL certificate: a resource you create from a PEM pair and attach directly to a target HTTPS proxy, up to 15 of them per proxy. The second is Certificate Manager, whose certificates a proxy can also reference directly, up to 100. The third is a Certificate Manager certificate map, a lookup table that matches an incoming hostname to a certificate and holds thousands of entries by default.
Most guides you will find only cover the first one, because it is the path the console has offered for the longest. That is fine until you hit one of two walls. The first is arithmetic: fifteen certificates on one proxy sounds generous until a platform team is fronting a few dozen customer domains. The second is compatibility, and it is the one that surprises people — Compute Engine Google-managed SSL certificates are not supported on regional external Application Load Balancers, regional internal Application Load Balancers, or cross-region internal Application Load Balancers. Pick one of those load balancer types and the classic path is simply not available for a managed certificate.
So the first thing worth writing down is not a command. It is which load balancer you are configuring and which of the three systems it accepts, because that determines whether the rest of this is a five-minute job or a redesign.
Google-managed, or bring your own?
A Google-managed certificate is free, renews itself, and is domain validated only. A certificate you obtain yourself can be organisation or extended validation, works on machines outside Google Cloud, and has to be replaced by you every time it expires. If the only requirement is that browsers stop complaining, the managed option is the shorter road and the rest of this guide is optional reading.
Two constraints push teams off it. One is validation level: nothing Google issues for free carries a verified organisation name in the subject, so a business that has been asked for OV or EV has to source the certificate elsewhere. The other is reach. A managed certificate exists to serve a Google Cloud load balancer and cannot be exported, so a company running a load balancer and a couple of Compute Engine VMs with their own web servers ends up managing two different things anyway.
There is a third, quieter reason, and it shows up during migrations. A Google-managed certificate will not finish provisioning until the domain already resolves to the load balancer's IP address, which means the cutover has to happen before the certificate exists. A certificate issued by a CA has no such ordering problem: it is valid the moment it is issued, so it can be installed and tested against the load balancer's IP before any DNS record moves.
The PEM files Google Cloud accepts
Google Cloud wants one PEM file holding the server certificate first and the intermediates after it in chain order, plus a separate PEM private key with no passphrase, using RSA or ECDSA. Two rules in Google's documentation reject files that look perfectly reasonable: the chain must be no more than five certificates long, and it must include at least one intermediate certificate. Google does not validate the chain for you beyond those checks, so ordering mistakes surface later as browser errors rather than upload failures.
That second rule has a consequence worth stating plainly: a self-signed certificate cannot be uploaded at all. It has no intermediate, so gcloud refuses the file outright. A self-hosted Nginx would have loaded the same file happily and left the browser to complain. If you are used to testing with a self-signed certificate before the real one arrives, that habit does not transfer.
Most CAs send the leaf and the intermediates as separate files. Concatenating them in the right order is the whole job:
# Leaf first, then the intermediates, in chain order.
cat your_domain.crt intermediate.crt > server.crt
# Check what you built before uploading it.
openssl crl2pkcs7 -nocrl -certfile server.crt \
| openssl pkcs7 -print_certs -nooutThe second command prints the subject and issuer of every certificate in the file. Read it top to bottom: each certificate's issuer should be the next certificate's subject. If the order is wrong, or a root has crept in from a bundle you downloaded, this is where you see it. The mechanics of what should be in that file, and why the root is deliberately left out, are covered in our guide to the SSL certificate chain.
If the private key is protected by a passphrase, strip it before uploading, since Google Cloud will not accept an encrypted key:
openssl rsa -in encrypted.key -out server.keyAll of this assumes you already have a certificate in hand. If that step is still open, the SSL certificates we issue through Certum arrive as exactly these PEM files, with the intermediates the CA actually published rather than a bundle reassembled from a support article. The certificate signing request that produces them is the same one you would generate for any other server, and our walkthrough of what a CSR is and how to generate one covers the OpenSSL side.
The classic path: a Compute Engine certificate
Creating a Compute Engine SSL certificate takes one command, and attaching it to the target proxy takes a second. The resource is global for a global load balancer and regional for a regional one, and the two are not interchangeable — a regional proxy will not accept a global certificate, which is the single most common reason the attach step fails with a resource-not-found error that reads as though the certificate does not exist.
# Create the certificate resource (global load balancer).
gcloud compute ssl-certificates create www-example-2026-08 \
--certificate=server.crt \
--private-key=server.key \
--global
# Attach it to the target HTTPS proxy.
gcloud compute target-https-proxies update my-https-proxy \
--ssl-certificates=www-example-2026-08 \
--globalNote what the second command does not do. It does not add the certificate to the proxy's list; it replaces the list. Running it with one name detaches everything else that was attached, which is fine on a proxy serving a single hostname and destructive on one serving several. To keep the existing certificates, name all of them:
gcloud compute target-https-proxies update my-https-proxy \
--ssl-certificates=www-example-2026-08,api-example-2026-08 \
--globalFor a regional load balancer, swap --global for --region=REGION in both commands. Naming the resource after the domain and the month it was issued, as above, is a small habit that pays off quickly: because certificates can never be edited, a year of 200-day renewals leaves a list of near-identical resources, and a date in the name is the only thing that makes it obvious which one is current.
The Certificate Manager path
Certificate Manager stores the same PEM material under a different resource type, and adds the certificate map — a lookup table that picks a certificate based on the hostname in the TLS handshake. Uploading is one command. Deciding whether to attach the certificate directly or through a map is the real choice, and it comes down to how many hostnames one proxy has to serve now and in two years.
# Upload the same PEM pair to Certificate Manager.
gcloud certificate-manager certificates create www-example-2026-08 \
--certificate-file=server.crt \
--private-key-file=server.keyAttached directly, that certificate behaves much like the Compute Engine version, with a ceiling of 100 per target proxy instead of 15. A map raises the ceiling into the thousands and changes the shape of the work: instead of editing the proxy on every renewal, you edit a map entry, and the proxy never changes again.
# Create a map, add an entry for one hostname, attach the map.
gcloud certificate-manager maps create example-map
gcloud certificate-manager maps entries create www-entry \
--map=example-map \
--certificates=www-example-2026-08 \
--hostname="www.example.com"
gcloud compute target-https-proxies update my-https-proxy \
--certificate-map=example-map \
--globalA map can also carry a primary entry, whose hostname is fixed as <PRIMARY> and cannot be changed. It is the fallback served to clients whose requested hostname matches no other entry, including clients that send no SNI at all. Leaving it out is a legitimate choice; forgetting it and then discovering that some old client gets a handshake failure is not.
One point worth weighing before building a large map: entries and certificates both multiply the renewal work, and a single certificate covering many names does not. A wildcard certificate covering every subdomain of one zone collapses dozens of map entries into one, which matters more with each cut to certificate lifetimes. Maps are the right tool for many unrelated domains, not for many subdomains of the same one.
Why the certificate map quietly wins
If a target proxy references both a certificate map and one or more directly attached certificates, the load balancer uses the map and ignores the directly attached certificates completely. Google's documentation states this for both Compute Engine SSL certificates and Certificate Manager certificates attached without a map. Nothing errors, nothing warns, and the console keeps showing the ignored certificates exactly as though they were in use.
This is the failure mode behind a symptom that otherwise makes no sense: a certificate is created, attached, visible, not expired, and browsers still receive the old one. It usually appears when a proxy is migrated to Certificate Manager and the old attachments are left behind as a safety net, which is precisely backwards — the safety net is the thing being ignored, and the map is carrying the whole load.
Checking takes one command:
gcloud compute target-https-proxies describe my-https-proxy \
--global \
--format="yaml(certificateMap, sslCertificates)"If certificateMap has a value, that is what is being served, whatever else the output lists. Pick one system per proxy and detach the other; keeping both attached is a trap waiting for whoever handles the next renewal, and it will usually be someone who was not there for the migration.
Renewal: nothing rotates a certificate you supplied
A self-managed certificate is never renewed automatically on Google Cloud, and it cannot be updated in place either. The private key on a certificate resource is write-only, supplied once at creation and never again, so every renewal produces a new resource that the target proxy or the map entry has to be repointed at. There is no command that swaps the contents of an existing certificate.
The order in the figure is what keeps the swap uneventful. Attaching the new certificate alongside the old one costs nothing, since a proxy holds up to 15 or 100 depending on the system, and it means a mistake in the new file is discovered while a working certificate is still serving traffic. Confirm with an explicit check against the load balancer rather than trusting the console:
echo | openssl s_client -connect 203.0.113.10:443 \
-servername www.example.com 2>/dev/null \
| openssl x509 -noout -subject -issuer -datesThen work out how often this comes back. Since March 15, 2026 a publicly trusted TLS certificate may not exceed 200 days under the CA/Browser Forum schedule introduced by ballot SC-081v3, which puts the job at roughly twice a year per load balancer. The same schedule cuts the ceiling to 100 days on March 15, 2027 and to 47 days on March 15, 2029, so a manual swap becomes about four times a year in 2027 and roughly eight in 2029. Anyone still doing this by hand at that point will want either a Google-managed certificate on the load balancers that support one, or an ACME client writing into Certificate Manager on a schedule.
The same maths applies to every cloud, and the shape of the work differs mainly in what each one calls the certificate object. Our guides to installing an SSL certificate on AWS and on Azure cover the equivalent decisions there, including which store each service can actually read from.
Why Google Cloud rejects a certificate that looks fine
Almost every rejection traces to one of five causes: the chain is missing its intermediate, the certificates are in the wrong order, the private key is still encrypted, the key and the certificate do not match, or the resource is regional when the proxy is global. The error text is rarely specific enough to tell them apart, so it is quicker to check all five than to read the message closely.
The key-mismatch check is the one people skip, and it is the fastest. These two commands print a hash each; if the hashes differ, the key does not belong to the certificate, usually because a CSR was regenerated at some point and the wrong key survived:
openssl x509 -noout -modulus -in server.crt | openssl md5
openssl rsa -noout -modulus -in server.key | openssl md5A Google-managed certificate fails differently. It sits in PROVISIONING and then reports FAILED_NOT_VISIBLE, which means Google tried to validate the domain and could not see it resolving to the load balancer's IP address. The two usual causes are a DNS A record that still points at the old host, and a proxying CDN in front of the load balancer that intercepts the validation request. Provisioning can take up to 60 minutes after DNS and load balancer changes have propagated, and propagation itself can take up to 72 hours depending on the TTL of the record you replaced — so patience is genuinely part of the diagnosis here, and re-creating the certificate before that window has passed just restarts the clock.
One last case has nothing to do with the certificate. If everything validates and the browser still shows the wrong one, go back to the precedence rule above and check whether a certificate map is attached to the proxy.
Frequently asked questions
If the certificate itself is still on your list
Everything above starts from a certificate you already hold. If you do not have one yet, the certificates we sell are issued by Certum from its own publicly trusted roots and arrive as the PEM leaf and intermediate files this guide concatenates, so the chain you upload is the one the CA published. Organisation and extended validation are both available, which is the gap a Google-managed certificate cannot fill.
Related reading
- Installing an SSL certificate on AWS — the same job where the certificate becomes an ARN and CloudFront only reads one Region.
- Installing an SSL certificate on Azure — one PFX instead of two PEM files, and two stores that refresh on different clocks.
- The SSL certificate chain — what belongs in the file you concatenate, and why the root stays out of it.