What it means
TLS verification asks two separate questions, and the error text tells you which one failed. Is this certificate issued by someone I trust? And does it actually cover the hostname I asked for? "Doesn't match any of the subject alternative names" is the second question answered no — the chain verified, the certificate is real, and it was issued for a different name.
On Lambda the usual cause is a VPC interface endpoint without private DNS. An endpoint gets its own DNS names, and if code reaches it by one of those, it is asking for a hostname that AWS's service certificate does not list. Enabling private DNS on the endpoint makes the service's normal hostname resolve to it privately, so the code keeps asking for the name the certificate was issued for and verification passes. The fix is a single property, and it is a configuration change rather than a code one.
The other shape of TLS failure reads differently and needs a different response. "Unable to get local issuer certificate", "unable to verify the first certificate", SSLCertVerificationError — those are trust-chain problems, usually a proxy re-signing traffic or a stale CA bundle vendored into the package. Reading which of the two you have before changing anything saves solving the wrong problem.
There is one fix worth naming in order to rule it out. Disabling certificate verification makes the error stop, and it removes exactly the protection that error exists to provide — every one of these failures is TLS reporting that the connection is not verifiably going where you think. Where a corporate proxy is legitimately re-signing traffic, the answer is to trust its CA explicitly, which keeps verification on and working. verify=False is not a fix, and it tends to survive far longer in a codebase than the incident that introduced it.
CloudWatch’s Errors metric: Whether CloudWatch’s Errors metric counts this depends on whether the error escaped your handler, which the log line alone does not settle. Counted only when the error escapes the handler. LogStitch classified the example below from its log level rather than an extracted error type.
What it looks like in CloudWatch
This is the shape the failure arrives in: the lines of one invocation scattered among everything else the log group received at the same moment.
CloudWatch Logs Before
6 raw lines, in the order CloudWatch delivered them.
LogStitch After
The same lines, grouped into the invocation they belong to.
Error2b7e9c31-4a08-4d62-9153-8c0f5a3e7b26
- 14:22:07.104PLAT
START RequestId: 2b7e9c31-4a08-4d62-9153-8c0f5a3e7b26 Version: $LATEST
- 14:22:07.110INFO
INFO Reading database credentials
- 14:22:07.402ERROR
ERROR Unable to execute HTTP request: Certificate for abc.us-east-1.amazonaws.com doesn't match any of the subject alternative names at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptTimeoutTrackingStage.execute2 lines - 14:22:07.588PLAT
END RequestId: 2b7e9c31-4a08-4d62-9153-8c0f5a3e7b26
- 14:22:07.588PLAT
REPORT RequestId: 2b7e9c31-4a08-4d62-9153-8c0f5a3e7b26 Duration: 484.11 ms Billed Duration: 485 ms Memory Size: 1024 MB Max Memory Used: 244 MB Status: error
The panel on the right is generated by running the excerpt on the left through the same parser that powers the free web stitcher — it is what the tool actually produces for this input, not an illustration of it.
How to confirm it from the logs
Read the hostname in the message and ask whether it is the one your code names. A regional service endpoint that your code never mentions — particularly one with an unfamiliar prefix — means the request was routed somewhere other than where the code intended, which is the VPC endpoint case.
Distinguish the two shapes. "Doesn't match any of the subject alternative names" is a name mismatch: verification worked and the certificate is for something else. "Unable to get local issuer certificate" or "unable to verify the first certificate" is a trust problem: the chain could not be validated, which is a different fix entirely.
Check whether the function is VPC-attached and whether an interface endpoint exists for the service. That combination plus this error is nearly diagnostic on its own.
Causes, most likely first
A VPC interface endpoint is in use without private DNS enabled
Check PrivateDnsEnabled on the endpoint. With it off, the service's public hostname does not resolve to the endpoint, and code reaching the endpoint's own DNS name asks for a hostname the certificate does not cover. Turning it on makes the standard hostname resolve privately and the certificate match.
A corporate TLS-inspecting proxy is re-signing traffic
Look for this only on VPC-attached functions whose traffic leaves through inspection infrastructure. A proxy presenting its own certificate fails verification unless its CA is trusted, and the message then names the proxy's certificate rather than the service's.
The endpoint URL is being overridden in code
Search for an endpoint_url or equivalent override. Pointing a client at a custom host — a test double left in, an endpoint copied from another region — makes it request a hostname the real certificate does not include.
The runtime's CA bundle is stale or has been replaced
Check whether the code bundles its own certificate store, or sets REQUESTS_CA_BUNDLE or SSL_CERT_FILE. A vendored CA bundle that has not been updated produces trust failures rather than name mismatches, and pinning one inside a Lambda is rarely worth the maintenance.
Fixes
Enable private DNS on the interface endpoint
This is the fix for the common case and it needs no code change. With private DNS the service's normal hostname resolves to the endpoint inside your VPC, so the certificate matches because you are asking for the name it was issued for.
yamlSecretsManagerEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref Vpc
ServiceName: !Sub "com.amazonaws.${AWS::Region}.secretsmanager"
VpcEndpointType: Interface
PrivateDnsEnabled: true # without this, the certificate will not match
SubnetIds: !Ref PrivateSubnets
SecurityGroupIds: [!Ref EndpointSecurityGroup]
Stop overriding the endpoint URL
Let the SDK construct the endpoint from the region. An override is occasionally necessary and much more often a leftover, and it is the one change that makes a client request a hostname the certificate was never issued for.
python# Leftover from local testing — asks for a hostname no AWS cert covers.
# s3 = boto3.client("s3", endpoint_url="https://s3.internal.test")
s3 = boto3.client("s3")
Verify what the endpoint actually presents
Reading the certificate's subject alternative names settles in one command whether this is a name mismatch or a trust failure.
bashopenssl s_client -connect secretsmanager.us-east-1.amazonaws.com:443 \
-servername secretsmanager.us-east-1.amazonaws.com </dev/null 2>/dev/null |
openssl x509 -noout -text | grep -A1 'Subject Alternative Name'
Trust the inspecting CA rather than disabling verification
Where a proxy is re-signing traffic, add its CA to the bundle the runtime uses. Turning verification off makes the error disappear and removes the protection it exists to provide — it is not a fix, and it is worth saying so explicitly.
pythonimport boto3
# Trust the corporate CA, packaged with the function.
s3 = boto3.client("s3", verify="/var/task/certs/corporate-ca.pem")
# Never: verify=False
Also seen as
The same underlying failure, worded differently by a different runtime, SDK version, or logging layer. All of these land here — there is no separate page for each phrasing.
Related errors
Errors that show up alongside this one, or that people mistake for it.
References
- AWS Lambda Developer Guide — Troubleshoot networking issues
- Amazon VPC User Guide — Access an AWS service using an interface VPC endpoint
LogStitch finds this automatically, across every invocation in your account.
Paste a log excerpt into the free web stitcher and see it grouped, classified, and measured in your browser — nothing is uploaded. Or run the Mac app against your own AWS profiles and get the same view over every function you own.