AWS CLI "SSL certificate verify failed"? Fix It

Package aws-cli/2.37.3, openssl, ca-certificates on RHEL 10.2
AWS Region ap-south-1 (Mumbai) for the examples; TLS validation applies to whichever Regional hostname the CLI reaches
Lab environment Workstation with AWS CLI v2 and configured credentials — AWS CLI tutorial
Install AWS CLI on Ubuntu · Install AWS CLI on Debian
Privilege Valid AWS credentials for the API being tested; sudo only when installing a corporate CA into the system trust store
Scope Why the AWS CLI returns SSL validation failed or certificate verify failed, how to inspect the presented certificate chain with openssl s_client, how to build a PEM CA bundle that includes your corporate root, and how to configure --ca-bundle, AWS_CA_BUNDLE, or ca_bundle. Covers TLS-intercepting proxies and wrong bundle paths. Does not cover endpoint connection failures (TCP/DNS), missing credentials, or AccessDenied after TLS succeeds.
Related guides Could not connect to endpoint URL
Unable to locate credentials
InvalidClientTokenId
AWS CLI Tutorial
AWS Tutorial
Short on time?Beta Get the gist of this 12-minute read in seconds, then ask follow-up questions

SSL certificate verify failed means the AWS CLI reached the HTTPS endpoint, but certificate validation rejected the certificate chain presented by the server or proxy.

DNS and the initial network connection already worked, so start with certificate trust, CA bundles, proxy interception, and hostname validity—not IAM permissions.

On enterprise networks, a TLS-inspecting proxy often presents a certificate signed by an internal root CA. Browsers may trust that CA through a managed policy, while the AWS CLI still validates against its own CA bundle unless you add the corporate root.

The examples use AWS CLI 2.37.3 on RHEL 10.2. The same openssl checks and --ca-bundle / AWS_CA_BUNDLE / ca_bundle settings apply on other Linux distributions and in CI containers behind corporate proxies.

      aws sts get-caller-identity
                |
                v
  AWS CLI chooses HTTPS endpoint
                |
                v
          TCP connection
                |
                v
  TLS handshake + certificate validation
                |
      +---------+---------+
      |                   |
    trusted             rejected
      |                   |
      v                   v
API request reaches   SSL certificate
AWS                   verify failed
      |
      v
AWS authentication / authorization
Symptom Most likely area First check
unable to get local issuer certificate Missing corporate or private root CA openssl s_client chain + issuer
No such file or directory on AWS_CA_BUNDLE Wrong bundle path ls the file; aws configure get ca_bundle
NO_CERTIFICATE_OR_CRL_FOUND Empty or non-PEM bundle file openssl x509 -in bundle.pem -text -noout
Browser works; CLI fails Browser trusts CA the CLI does not Compare browser cert issuer with CLI bundle
--no-verify-ssl succeeds Trust issue confirmed Fix CA bundle; do not leave verification off

What the TLS Error Means

SSL validation failed appears after the CLI opens HTTPS to the service hostname. The CLI must trust the presented certificate chain before the API request can complete.

A missing corporate root CA produces:

bash
aws s3 ls --endpoint-url https://127.0.0.1:18443
output
aws: [ERROR]: SSL validation failed for https://127.0.0.1:18443/ [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1082)

The hostname in the message is the endpoint whose certificate failed validation. unable to get local issuer certificate usually means the CLI could not find a trusted issuer for the presented chain—common when a proxy re-signs TLS with an internal CA.

Error substring Likely cause
unable to get local issuer certificate Corporate or private root CA not in the CLI trust bundle
self-signed certificate in certificate chain Untrusted self-signed cert in the chain
hostname doesn't match / subjectAltName Certificate SAN does not match the hostname
[Errno 2] No such file or directory on AWS_CA_BUNDLE Bundle path is wrong or missing
NO_CERTIFICATE_OR_CRL_FOUND Bundle file is empty or not PEM

This is not AccessDenied (authorization after TLS) and not Could not connect to the endpoint URL (TCP/DNS failure before TLS completes).


Inspect the Certificate Chain

Before changing AWS configuration, inspect what certificate the endpoint presents. Use the hostname and port from the error or from your proxy documentation.

Against a TLS endpoint that uses a private corporate CA:

bash
echo | openssl s_client \
  -connect 127.0.0.1:18443 \
  -servername 127.0.0.1 \
  -showcerts 2>&1 |
  grep -E 'verify error|Verify return code|subject=|issuer='
output
verify error:num=20:unable to get local issuer certificate
verify error:num=21:unable to verify the first certificate
subject=CN=127.0.0.1
issuer=CN=Lab Corporate Root CA, O=GoLinuxCloud Lab
Verify return code: 21 (unable to verify the first certificate)

verify error:num=20 and return code 21 mean OpenSSL does not trust the issuer with the system default store. The issuer= field identifies the CA that signed the presented certificate. Use it to determine which corporate PKI chain is involved, then obtain the appropriate root CA—and any required intermediates—from your security team.

Re-run with the corporate root CA file your security team provides:

bash
echo | openssl s_client \
  -connect 127.0.0.1:18443 \
  -CAfile /etc/ssl/corp/corp-root-ca.pem \
  -showcerts 2>&1 |
  grep -E 'verify error|Verify return code|subject=|issuer='
output
subject=CN=127.0.0.1
issuer=CN=Lab Corporate Root CA, O=GoLinuxCloud Lab
Verify return code: 0 (ok)

Return code 0 (ok) confirms the CA file completes the chain. If this succeeds, you have identified a CA chain the CLI can trust. Use that CA bundle in the next step.

For a real AWS Regional hostname behind a proxy, replace 127.0.0.1:18443 with the hostname from the error—for example s3.ap-south-1.amazonaws.com:443—and keep -servername aligned with the hostname the CLI uses:

bash
echo | openssl s_client \
  -connect s3.ap-south-1.amazonaws.com:443 \
  -servername s3.ap-south-1.amazonaws.com \
  -showcerts 2>&1 |
  grep -E 'verify error|Verify return code|subject=|issuer='

Install and Trust the Correct CA

Once openssl s_client succeeds with -CAfile, install or reference that root CA consistently.

AWS_CA_BUNDLE points the CLI at the CA bundle it should use for HTTPS verification. In a corporate network, that bundle may need to include both the normal public CA roots and your organization's corporate root or intermediate CA certificates.

Build a combined bundle on RHEL 10:

bash
sudo mkdir -p /etc/ssl/corp
cat /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem corp-root-ca.pem \
  > /etc/ssl/corp/aws-ca-bundle.pem

On RHEL 10, you can also add the corporate root to the system trust store so OS tools pick it up:

bash
sudo cp corp-root-ca.pem /etc/pki/ca-trust/source/anchors/

Rebuild the system trust store:

bash
sudo update-ca-trust extract

Adding a CA to the RHEL system trust store can fix tools that use the OS trust store, such as curl. Do not assume that alone fixes AWS CLI. Test the CLI separately and, if necessary, configure its documented CA bundle using --ca-bundle, AWS_CA_BUNDLE, or ca_bundle.

Keep the combined PEM file at a stable path—for example /etc/ssl/corp/aws-ca-bundle.pem—even after importing the root into the system store. You will point the CLI at that bundle in the next section.

Confirm the file contains PEM certificates:

bash
grep -c 'BEGIN CERTIFICATE' /etc/ssl/corp/aws-ca-bundle.pem

A combined bundle should report at least two certificates—the standard CA bundle plus your corporate root. A count of 0 means the file is empty or not PEM.

To inspect every certificate in the bundle:

bash
openssl crl2pkcs7 -nocrl \
  -certfile /etc/ssl/corp/aws-ca-bundle.pem |
openssl pkcs7 -print_certs -noout

Each block should list a subject= line. A blank file or DER data mislabeled as .pem causes NO_CERTIFICATE_OR_CRL_FOUND when referenced from the CLI.

The best functional test is still an AWS CLI call with --ca-bundle:

bash
aws sts get-caller-identity \
  --ca-bundle /etc/ssl/corp/aws-ca-bundle.pem

If that call gets past SSL validation, the CLI can use the bundle.


Configure the AWS CLI CA Bundle

The AWS CLI's documented CA-bundle settings use this precedence:

--ca-bundle /path/to/bundle.pem
            |
            v overrides
AWS_CA_BUNDLE=/path/to/bundle.pem
            |
            v overrides
ca_bundle=/path/to/bundle.pem in ~/.aws/config

For a one-command test, --ca-bundle is useful because it does not change the shell or profile configuration.

Test the bundle against a real Regional endpoint:

bash
aws sts get-caller-identity \
  --ca-bundle /etc/ssl/corp/aws-ca-bundle.pem

Retry the same HTTPS call that failed—the CLI should accept the proxy-signed chain:

bash
aws s3 ls \
  --endpoint-url https://127.0.0.1:18443 \
  --ca-bundle /etc/ssl/corp/aws-ca-bundle.pem

The lab endpoint at 127.0.0.1:18443 is an S3-compatible test endpoint configured for this reproduction. If the SSL validation error disappears and the command proceeds to an HTTP/API-level response, certificate validation has succeeded—even if the endpoint then returns another application-level error.

When the one-command test works, choose persistent configuration.

For one shell session:

bash
export AWS_CA_BUNDLE=/etc/ssl/corp/aws-ca-bundle.pem

On an AWS CLI profile:

bash
aws configure set ca_bundle /etc/ssl/corp/aws-ca-bundle.pem --profile work

Confirm the profile stored the path you expect:

bash
aws configure get ca_bundle --profile work
output
/etc/ssl/corp/aws-ca-bundle.pem

A wrong path against a real Regional endpoint fails before IAM runs:

bash
AWS_CA_BUNDLE=/etc/nonexistent-ca-bundle.pem aws sts get-caller-identity
output
aws: [ERROR]: SSL validation failed for https://sts.ap-south-1.amazonaws.com/ [Errno 2] No such file or directory

After fixing the path, unset a bad override before retesting:

bash
unset AWS_CA_BUNDLE

With the default or profile bundle restored, STS should answer over TLS:

bash
aws sts get-caller-identity --query Account --output text
output
123456789012

A numeric account ID confirms TLS to the Regional STS endpoint succeeded and credentials signed the request.

Do not edit the bundled CA file inside the AWS CLI installation—for example /usr/local/aws-cli/.../botocore/cacert.pem. Upgrades can replace it. Use --ca-bundle, AWS_CA_BUNDLE, or ca_bundle instead.


Check Corporate Proxy Interception

A TLS-inspecting proxy sits between your computer and AWS. It opens the HTTPS connection, inspects the traffic, and presents your machine with a new certificate signed by the company's CA.

AWS CLI
   |
   | certificate signed by Corporate CA
   v
Corporate proxy
   |
   | normal AWS TLS certificate
   v
AWS endpoint

The CLI sees the proxy's certificate, not the original AWS certificate, unless you connect through a tunnel that preserves end-to-end TLS.

List proxy variables in the same shell:

bash
env | grep -i proxy

If HTTPS_PROXY is set, traffic may pass through an interceptor. Combine proxy configuration with the correct CA bundle—fixing only the proxy URL while omitting the corporate root still leaves certificate verify failed.

NO_PROXY is an exception list: matching destinations bypass the proxy. For EC2 instance metadata, AWS documents excluding 169.254.169.254 so IMDS calls do not loop through a proxy.

If the browser works but AWS CLI fails, inspect the certificate issuer in the browser or with openssl s_client, then obtain the corporate root CA and any required intermediate CA certificates from your security or network team. Do not solve this by trusting an individual AWS or proxy-generated site certificate. Browsers on managed laptops often receive the corporate root through Group Policy or an MDM profile; a minimal Linux VM or container may not.


Why --no-verify-ssl Is Not the Fix

--no-verify-ssl skips certificate validation. Use it only as a short diagnostic to confirm the failure is TLS trust—not as the permanent solution.

bash
aws s3 ls --endpoint-url https://127.0.0.1:18443 --no-verify-ssl
output
urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host '127.0.0.1'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings

If the same command gets past the SSL verification error only when --no-verify-ssl is added, certificate validation is the failing layer. The service may legitimately return an IAM or API error afterward—you do not need exit code 0 to confirm this.

Do not add --no-verify-ssl to scripts, cron jobs, or CI pipelines. AWS documents that it disables certificate verification and should not be the permanent fix. Install the correct CA bundle and set --ca-bundle, AWS_CA_BUNDLE, or ca_bundle instead. Disabling verification exposes API traffic to interception and breaks compliance on many enterprise networks.


Verify

After the corporate CA is in place and the bundle path is correct, confirm TLS and API access.

Clear stale overrides:

bash
unset AWS_CA_BUNDLE

Set the bundle on the profile you use for AWS work:

bash
aws configure set ca_bundle /etc/ssl/corp/aws-ca-bundle.pem

Run a lightweight Regional call:

bash
aws sts get-caller-identity --query Account --output text
output
123456789012

If the failing command targeted S3, rerun that same command without --no-verify-ssl. SSL errors should be gone; any remaining message will be IAM or API-level, not certificate validation.


Troubleshooting

Symptom Likely cause Fix
unable to get local issuer certificate Corporate root not in CLI bundle Build combined CA bundle; set --ca-bundle, AWS_CA_BUNDLE, or ca_bundle
No such file or directory on SSL error Wrong AWS_CA_BUNDLE path Fix path; verify with aws configure get ca_bundle
NO_CERTIFICATE_OR_CRL_FOUND Invalid PEM bundle Re-export root CA as PEM; verify with openssl x509
hostname doesn't match / SAN mismatch Proxy or custom endpoint presented a certificate for another hostname Verify endpoint URL and proxy certificate; do not solve by adding random CAs or disabling verification
certificate has expired / certificate is not yet valid Expired proxy cert or incorrect client clock Check date; replace or renew the certificate if the clock is correct
Browser OK; CLI fails Browser trusts CA the CLI does not Install same root for CLI; do not rely on browser-only policy
--no-verify-ssl bypasses SSL error Trust issue confirmed Add CA bundle; remove --no-verify-ssl from automation
Error references unexpected AWS hostname/Region Wrong Region or endpoint configuration Run aws configure list; verify the hostname/Region before changing certificates
Error mentions proxy host Proxy TLS or connectivity Fix proxy URL and trust the proxy signing CA

Summary

SSL certificate verify failed means HTTPS reached the endpoint, but the AWS CLI did not trust the presented certificate chain. Start with the hostname in the error and confirm the chain with openssl s_client before touching IAM or credentials.

Corporate proxies and private CAs require a PEM bundle that includes the signing root—often a standard CA bundle plus the corporate root. Test with --ca-bundle first, then persist with AWS_CA_BUNDLE or ca_bundle. A wrong bundle path fails with No such file or directory even against real Regional endpoints such as sts.ap-south-1.amazonaws.com.

--no-verify-ssl is useful only to prove the issue is TLS trust. The durable fix is building the correct CA bundle and pointing the CLI at that PEM file. Do not edit the CLI's bundled cacert.pem. When aws sts get-caller-identity returns an account ID again, TLS validation is healthy for that profile.


References


Frequently Asked Questions

What does AWS_CA_BUNDLE do?

AWS_CA_BUNDLE tells the AWS CLI which PEM file to use when validating HTTPS server certificates. In a corporate network, that bundle may need to include both public CA roots and your organization's corporate root or intermediate CA certificates. It overrides the default embedded CA list for the CLI process. The --ca-bundle command-line option overrides both AWS_CA_BUNDLE and ca_bundle for a single command.

Can I use a private CA?

Yes. Export the private or corporate root CA as a PEM file, verify the chain with openssl s_client -CAfile, then combine it with a standard CA bundle if needed. Test with --ca-bundle, then set AWS_CA_BUNDLE or ca_bundle to that file. The CA does not need to be a public Web PKI issuer—it must be the issuer your TLS endpoint actually presents.

Why does the browser work but AWS CLI fail?

Managed browsers often install corporate root CAs through OS or browser policy. The AWS CLI uses its own CA configuration, which does not automatically include those roots. Install the same corporate CA for the CLI with --ca-bundle, AWS_CA_BUNDLE, or ca_bundle.

Finished reading?Beta Get the key takeaways in seconds, then ask follow-up questions
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with 15+ years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)