Troubleshooting Google Public CA and acme.sh
A focused troubleshooting companion for Google Public CA EAB registration, DNS-01 validation, installation, and renewal with acme.sh.

Start with the current setup guide: Google Trust Services Certificates with acme.sh. This companion intentionally avoids guessed quotas and destructive “reset everything” commands.
EAB registration fails
Confirm four facts before changing local state:
- The selected Google Cloud project is the project that created the EAB secret.
publicca.googleapis.comis enabled.- The caller can create external account keys.
keyIdandb64MacKeywere copied as complete, separate values.
Google documents two easy-to-miss rules: the EAB secret must be used within seven days and can register only one ACME account. If it expired or was consumed, create a new secret. Do not delete acme.sh’s internal CA directory as a first response.
Check the client and server selection:
~/.acme.sh/acme.sh --version
~/.acme.sh/acme.sh --register-account \
--server google \
--accountemail admin@example.com \
--eab-kid 'YOUR_KEY_ID' \
--eab-hmac-key 'YOUR_B64_MAC_KEY' \
--debug 2
Do not paste debug output publicly before checking it for credentials and account identifiers. Production and staging are separate ACME environments; do not assume an EAB secret from one will register an account in the other.
DNS-01 validation fails
Find the authoritative name servers, then ask one directly for the challenge record:
dig +short NS example.com
dig @ns1.example-dns.net +short TXT _acme-challenge.example.com
If the authoritative server lacks the expected value, waiting on a public resolver will not repair the API call. Check that the Cloudflare token is limited to the correct zone, has DNS edit permission, and that CF_Zone_ID belongs to that zone.
For a certificate containing both example.com and *.example.com, two authorizations can use the same TXT owner. Multiple temporary TXT values may legitimately coexist. Do not delete records blindly while another order is active.
The website still serves the old certificate
Inspect the public endpoint:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -noout -serial -issuer -dates
If issuance succeeded but this output did not change, inspect the file paths configured in the web server. Usually the answer is not another issuance; it is installing to stable paths and successfully reloading the service:
~/.acme.sh/acme.sh --install-cert --ecc -d example.com \
--key-file /etc/nginx/ssl/example.com/privkey.pem \
--fullchain-file /etc/nginx/ssl/example.com/fullchain.pem \
--reloadcmd 'sudo nginx -t && sudo systemctl reload nginx'
--install-cert saves the reload action for renewals. Serving files directly from acme.sh’s internal certificate directory bypasses that stable installation contract.
Automatic renewal does not happen
Check each link in the chain:
crontab -l | grep acme.sh
~/.acme.sh/acme.sh --info -d example.com
timedatectl status
The DNS token must still work, the client must be scheduled, destination files must remain writable, and the reload command must return success. A renewed file is not enough if Nginx still holds the old certificate.
Monitor the public endpoint from another machine and alert well before expiry. That one observation covers issuance, installation, reload, DNS routing, and the certificate a client actually receives.
Corrections to the old article
The previous version listed certificate limits without a Google source, claimed EAB keys did not expire, suggested unsupported gcloud list commands, required billing without evidence, and recommended deleting internal acme.sh state. Those claims and procedures have been removed.
