Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Ansible By James Joyner IV · · 9 min read

Ansible Error Guide: 'certificate verify failed' ansible-galaxy x509 TLS Error

Fix ansible-galaxy's 'SSL: CERTIFICATE_VERIFY_FAILED' x509 error: diagnose missing CA bundles, proxies, expired certs, and self-signed Galaxy/Automation Hub endpoints.

  • #ansible
  • #troubleshooting
  • #errors
  • #galaxy

Exact Error Message

ERROR! Unknown error when attempting to call Galaxy server 'default'.
HTTPSConnectionPool(host='galaxy.ansible.com', port=443): Max retries exceeded with url: /api/
(Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed:
unable to get local issuer certificate (_ssl.c:1006)')))

You may also see the variants certificate has expired, self-signed certificate in certificate chain, or hostname mismatch, all under the same CERTIFICATE_VERIFY_FAILED header.

What the Error Means

When ansible-galaxy installs a role or collection, it makes an HTTPS request to a Galaxy server (the public galaxy.ansible.com, a private Automation Hub, or a pull-through proxy). Python’s TLS stack validates the server’s x509 certificate against a trusted CA bundle. If it cannot build a trust chain to a known root, the certificate is expired, or the hostname does not match, validation fails and the request is aborted before any collection is downloaded.

This is a TLS trust problem on the control node, not a problem with the collection itself.

Common Causes

  • The control node’s CA bundle is missing or outdated, so the issuing CA is unknown (unable to get local issuer certificate).
  • A corporate TLS-inspecting proxy re-signs traffic with an internal CA that is not in the system trust store (self-signed certificate in certificate chain).
  • A private Automation Hub or internal Galaxy mirror uses a self-signed or internally issued certificate.
  • The server certificate genuinely expired (certificate has expired).
  • requests/certifi is using its own bundled CA store that differs from the OS store.
  • The endpoint URL uses an IP or alternate name not present in the certificate’s SAN (hostname mismatch).

How to Reproduce the Error

Install a collection from behind a TLS-inspecting proxy without trusting its CA:

ansible-galaxy collection install community.general -vvv
ERROR! Unknown error when attempting to call Galaxy server 'default'.
... SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed:
self-signed certificate in certificate chain (_ssl.c:1006)'))

Or target a private hub with an internal cert:

ansible-galaxy collection install mycorp.platform -s https://hub.internal/api/galaxy/ -vvv

Diagnostic Commands

Inspect the exact certificate the server is presenting and whether it verifies:

openssl s_client -connect galaxy.ansible.com:443 -servername galaxy.ansible.com </dev/null 2>/dev/null | openssl x509 -noout -issuer -subject -dates

Find which CA bundle Python is using:

python3 -c "import ssl; print(ssl.get_default_verify_paths())"
python3 -c "import certifi; print(certifi.where())"

Confirm whether a proxy is in play (it usually is, when you see a self-signed chain):

env | grep -i proxy

Test the raw HTTPS handshake the way Galaxy would:

curl -v https://galaxy.ansible.com/api/ 2>&1 | grep -iE "issuer|verify|SSL"

Step-by-Step Resolution

  1. Read the specific reason. unable to get local issuer certificate and self-signed certificate in certificate chain are trust-store problems. certificate has expired is the server’s fault. hostname mismatch is a SAN problem.

  2. Update the system CA bundle if the issuer is simply unknown:

sudo update-ca-certificates        # Debian/Ubuntu
sudo update-ca-trust               # RHEL/Fedora
  1. Trust a corporate or internal CA. Get the proxy/hub root CA PEM and install it:
sudo cp corp-root-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
  1. Point ansible-galaxy at a specific CA bundle if you cannot modify the system store. Set GALAXY_IGNORE_CERTS=False and reference the bundle via the environment Python uses:
REQUESTS_CA_BUNDLE=/etc/ssl/certs/corp-bundle.pem ansible-galaxy collection install community.general
  1. Fix certifi drift. If Python uses a stale certifi store, update it:
pip install --upgrade certifi
  1. For an expired or mismatched server cert, fix the server. Renew the certificate or correct its SAN; do not work around it on every client.

  2. As a last resort for trusted internal mirrors only, you can ignore verification for one command. Treat this as a temporary, deliberate exception:

ansible-galaxy collection install mycorp.platform -s https://hub.internal/api/galaxy/ --ignore-certs

Prevention and Best Practices

  • Distribute your corporate/proxy root CA to every control node and CI runner through configuration management so the trust store is always complete.
  • Keep ca-certificates and certifi patched; expired or removed roots cause sudden, confusing failures.
  • Pin the CA bundle explicitly in CI with REQUESTS_CA_BUNDLE so builds do not depend on whatever store the base image ships.
  • Monitor certificate expiry on private Automation Hub endpoints and renew ahead of time.
  • Avoid --ignore-certs in pipelines; it disables a real protection and tends to become permanent.
  • Configure Galaxy servers explicitly in ansible.cfg so you know exactly which endpoint and trust settings apply.
  • Failed to import the required Python library — a different dependency problem, not TLS.
  • Max retries exceeded ... Connection refused — the endpoint is unreachable, not untrusted.
  • HTTP Error 401/403 from Galaxy — authentication/token issue, not certificate validation.
  • tlsv1 alert protocol version — a TLS version mismatch rather than a trust-chain failure.

Frequently Asked Questions

Why does curl work but ansible-galaxy fails? curl may use the OS trust store while Python’s requests/certifi uses its own bundle. Update certifi or set REQUESTS_CA_BUNDLE to align them.

We are behind a TLS-inspecting proxy. What is the right fix? Install the proxy’s root CA into the system trust store with update-ca-certificates / update-ca-trust, or point REQUESTS_CA_BUNDLE at a bundle that includes it. The proxy re-signs traffic, so its CA must be trusted.

Is --ignore-certs safe? Only for a trusted internal mirror on a controlled network, and ideally only temporarily. It disables certificate verification entirely, which removes MITM protection.

The server cert expired — can I fix it client-side? No. Renew the server certificate. Working around expiry on every client is fragile and insecure. For more dependency and supply-chain patterns, see the Ansible guides.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.