Google Cloud Platform offers two paths for SSL certificates on its load balancers: Google-managed certificates that auto-renew, and self-managed certificates that you provision and upload yourself. If you're using anything beyond the first category — or if you run HTTPS directly on Compute Engine instances, Cloud Run custom domains, or GKE ingress controllers — certificate expiry monitoring remains your responsibility.
This guide covers how GCP handles SSL internally, where the gaps are, and how to set up external monitoring for all your GCP-hosted endpoints.
Google-managed SSL certificates attached to an external HTTPS Load Balancer are provisioned and renewed by Google automatically. You specify domains, Google provisions a certificate via Google Trust Services, and renewal happens without any action on your part — typically 30 days before expiry.
This works reliably when:
If you've uploaded a certificate to GCP — from your own CA, a commercial CA, or an internal PKI — GCP does not renew it. You get no alerts from the console when it approaches expiry. The load balancer will continue serving the expired certificate until you replace it, causing browser security warnings and breaking API clients that validate certs strictly.
Finding expiry dates via gcloud:
# List all SSL certificates in a project
gcloud compute ssl-certificates list --format="table(name, managed.status, expireTime)"
# Get details for a specific cert
gcloud compute ssl-certificates describe CERT_NAME \
--format="value(expireTime)"
The expireTime field shows the certificate expiry timestamp in RFC 3339 format. You can pipe this into a script that alerts when the expiry is within 30 days.
If you're terminating SSL on a GCE instance — Nginx, Apache, or any other server software — the certificate on that instance is entirely outside GCP's managed cert system. This is common for:
Check from the instance or externally:
echo | openssl s_client -servername DOMAIN \
-connect DOMAIN:443 2>/dev/null \
| openssl x509 -noout -enddate
GKE uses the GKE Ingress Controller or the Gateway API, which can provision Google-managed certificates via annotations. However, this only applies when using the networking.gke.io/managed-certificates annotation with an external load balancer.
If your GKE workloads use:
None of these are covered by GCP's managed certificate system.
Check cert expiry inside GKE via kubectl:
# List all TLS secrets and their expiry dates
kubectl get secrets -A -o json | python3 -c "
import sys, json, base64, datetime
from cryptography import x509
data = json.load(sys.stdin)
for item in data['items']:
if item.get('type') == 'kubernetes.io/tls':
cert_data = base64.b64decode(item['data'].get('tls.crt', ''))
if cert_data:
cert = x509.load_pem_x509_certificate(cert_data)
expiry = cert.not_valid_after
days = (expiry - datetime.datetime.utcnow()).days
ns = item['metadata']['namespace']
name = item['metadata']['name']
print(f'{ns}/{name}: {days} days ({expiry.strftime(\"%Y-%m-%d\")})')
"
Cloud Run custom domains use Google-managed certificates and renew automatically — but the provisioning can fail if DNS isn't correctly configured when you first map the domain. Once provisioned, you should still monitor externally to catch edge cases where renewal gets stuck.
Both Firebase Hosting and App Engine manage SSL automatically for custom domains via Google Trust Services. Renewal is automatic, but external monitoring provides a safety net if the domain ownership verification lapses or DNS changes interfere with renewal.
For a project-wide audit of self-managed certificates:
#!/bin/bash
# Check all self-managed GCP SSL certs and alert if expiring within 30 days
PROJECT="your-project-id"
THRESHOLD_DAYS=30
gcloud compute ssl-certificates list \
--project="$PROJECT" \
--filter="type=SELF_MANAGED" \
--format="csv[no-heading](name,expireTime)" | \
while IFS=',' read -r name expiry; do
expiry_epoch=$(date -d "$expiry" +%s 2>/dev/null || \
date -j -f "%Y-%m-%dT%H:%M:%S" "${expiry%%+*}" +%s)
days_left=$(( (expiry_epoch - $(date +%s)) / 86400 ))
if [ "$days_left" -le "$THRESHOLD_DAYS" ]; then
echo "ALERT: $name expires in $days_left days ($expiry)"
fi
done
GCP's built-in monitoring can alert on SSL certificate expiry through Uptime Checks in the Google Cloud Console:
This works for any HTTPS endpoint — not just GCP-hosted ones. The limitation is that it checks one domain at a time and counts against your uptime check quota (250 free checks per project, additional checks billed at ~$0.06/check/month).
| Certificate type | GCP auto-renews? | Recommended monitoring |
|---|---|---|
| Google-managed (HTTPS LB) | Yes | External check as safety net |
| Self-managed (HTTPS LB) | No | gcloud CLI script + external check |
| Compute Engine (Nginx/Apache) | No | External HTTPS check on instance |
| GKE / cert-manager | No (cert-manager manages) | kubectl cert audit + external check |
| Cloud Run custom domain | Yes (usually) | External check as safety net |
| Firebase/App Engine | Yes | External check as safety net |
Before setting up automated monitoring, check your GCP domain immediately — no login required:
Enter any domain to see days remaining, expiry date, and issuer. Works for GCP load balancers, Compute Engine, Cloud Run custom domains, and any HTTPS endpoint.
Check SSL expiry → Get expiry alerts →The most reliable approach for GCP environments combines:
For teams running multiple GCP projects or domains, a dedicated SSL monitoring service runs these checks externally and sends tiered alerts at 30, 14, 7, and 1 day before expiry — without requiring access to your GCP project credentials.
SSLWatch monitors SSL certificates externally and sends email alerts before they expire. No GCP credentials needed — just add your domains and we'll alert you at 30, 14, 7, and 1 day before expiry.
Join the SSLWatch waitlist → Free SSL checker →