Error: getaddrinfo EAI_AGAIN secretsmanager.us-east-1.amazonaws.com

Short answer

The DNS query timed out rather than being answered. EAI_AGAIN means temporary failure — the resolver did not reply in time, which on a VPC-attached Lambda almost always means the function cannot reach the resolver at all, not that DNS is briefly busy.

What it means

EAI_AGAIN is the resolver library reporting that a lookup did not complete in time. The name is short for "try again", and it exists because DNS is expected to be occasionally busy — a transient condition a retry would clear.

Inside a VPC-attached Lambda it usually means something else entirely. The function is not being told to wait its turn; it is failing to reach a resolver at all. The query goes out over UDP 53 to the VPC resolver and nothing comes back, so the library waits out its timeout and reports the only thing it can distinguish, which is that no answer arrived. A permanent routing or filtering problem and a momentarily overloaded resolver produce the identical error code.

That is why the most useful first question is not why is DNS slow but is this every lookup or some of them. A blocked NACL, a disabled enableDnsSupport, or a DHCP option set pointing at unreachable name servers all produce total failure: every invocation, every name, indefinitely. Load-related failures — the per-interface DNS packet rate ceiling, reached by a function fanning out at high concurrency — produce scattered failures that track your traffic curve. The first is a configuration fix; the second is usually solved by resolving less, which mostly means constructing SDK clients at module scope so each execution environment does one lookup rather than one per request.

Network ACLs deserve particular suspicion because of how they fail. They are stateless, unlike security groups, so allowing outbound UDP 53 does nothing on its own — the response arrives on an ephemeral port and needs its own inbound rule. A VPC configured by someone thinking in security-group terms looks completely correct and drops every DNS reply, and the resulting EAI_AGAIN gives no hint that the query itself left successfully.

Depends

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, so it reports the failure as caught.

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

7 raw lines, in the order CloudWatch delivered them.

2026-08-30T08:41:19.008Z START RequestId: 7e2c4b81-9f36-4d50-a217-6b8c3e0f5a41 Version: $LATEST
2026-08-30T08:41:19.012Z 7e2c4b81-9f36-4d50-a217-6b8c3e0f5a41 INFO Loading database credentials
2026-08-30T08:41:24.118Z 7e2c4b81-9f36-4d50-a217-6b8c3e0f5a41 ERROR Error: getaddrinfo EAI_AGAIN secretsmanager.us-east-1.amazonaws.com
at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)
at loadCredentials (/var/task/src/db.js:14:22)
2026-08-30T08:41:24.402Z END RequestId: 7e2c4b81-9f36-4d50-a217-6b8c3e0f5a41
2026-08-30T08:41:24.402Z REPORT RequestId: 7e2c4b81-9f36-4d50-a217-6b8c3e0f5a41 Duration: 5394.22 ms Billed Duration: 5395 ms Memory Size: 512 MB Max Memory Used: 112 MB Status: error

LogStitch After

The same lines, grouped into the invocation they belong to.

Error7e2c4b81-9f36-4d50-a217-6b8c3e0f5a41dur 5.39sbilled 5.39smem 112/512MBlogs 5
  1. 08:41:19.008PLAT
    START RequestId: 7e2c4b81-9f36-4d50-a217-6b8c3e0f5a41 Version: $LATEST
  2. 08:41:19.012INFO
    INFO	Loading database credentials
  3. 08:41:24.118ERROR
    ERROR	Error: getaddrinfo EAI_AGAIN secretsmanager.us-east-1.amazonaws.com
        at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26)
        at loadCredentials (/var/task/src/db.js:14:22)
    3 lines
  4. 08:41:24.402PLAT
    END RequestId: 7e2c4b81-9f36-4d50-a217-6b8c3e0f5a41
  5. 08:41:24.402PLAT
    REPORT RequestId: 7e2c4b81-9f36-4d50-a217-6b8c3e0f5a41	Duration: 5394.22 ms	Billed Duration: 5395 ms	Memory Size: 512 MB	Max Memory Used: 112 MB	Status: error
Error
Status
5.39s
Duration
5.39s
Billed
112/512MB
Memory
78%
Headroom
No
Cold start
LogLevelError
Error type

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

Time it. A lookup that fails after several seconds — often five, matching the resolver timeout — is a timeout; one that fails instantly is a different error wearing a similar name. Check the elapsed time between the log line before the failure and the failure itself.

Then check whether it is intermittent or total. Genuinely transient DNS pressure produces scattered failures under load. A VPC that cannot reach its resolver produces EAI_AGAIN on every lookup, from every invocation, forever — and the word "temporary" in the error is then actively misleading, because nothing about it is temporary.

Causes, most likely first

1

A network ACL or security group blocks UDP 53 to the VPC resolver

How to confirm

Check the subnet's network ACL for outbound UDP 53 and the corresponding inbound ephemeral return range. Security groups are stateful and rarely the culprit; NACLs are stateless, so an outbound rule without a matching inbound rule for return traffic silently drops every reply and every lookup times out.

2

A custom DHCP option set points at unreachable name servers

How to confirm

Look at the DHCP option set associated with the VPC. If it names on-premises or third-party resolvers, the function must actually be able to reach them — over a VPN, Direct Connect, or peering. When that path is down or was never built, every lookup times out while the configuration looks deliberate.

3

The function is under heavy concurrency and exceeding the per-ENI DNS limit

How to confirm

Correlate the failures with concurrent executions. There is a packets-per-second ceiling for DNS queries from a network interface, and a function fanning out at high concurrency — especially one resolving a fresh name on every invocation rather than reusing a client — can reach it. This is the case where the failures really are intermittent and load-shaped.

4

DNS resolution is disabled on the VPC

How to confirm

Check enableDnsSupport. With it off there is nothing listening at the VPC's .2 resolver address, so queries go unanswered rather than refused — which surfaces as a timeout rather than as a clear failure.

Fixes

Fix 1

Allow DNS traffic in the network ACL, in both directions

NACLs are stateless. An outbound rule for UDP 53 without an inbound rule for the ephemeral return ports drops every response, which is indistinguishable from an unreachable resolver. This is the single most common cause in a hand-built VPC.

bash# Outbound query
aws ec2 create-network-acl-entry --network-acl-id acl-0abc \
  --rule-number 110 --protocol udp --port-range From=53,To=53 \
  --cidr-block 0.0.0.0/0 --rule-action allow --egress

# Inbound response, on the ephemeral range
aws ec2 create-network-acl-entry --network-acl-id acl-0abc \
  --rule-number 110 --protocol udp --port-range From=1024,To=65535 \
  --cidr-block 0.0.0.0/0 --rule-action allow
Fix 2

Check the DHCP option set actually points somewhere reachable

A custom option set naming on-premises resolvers only works while the path to them does. Reverting to AmazonProvidedDNS is the fastest way to confirm whether the resolver choice is the problem.

bashaws ec2 describe-vpcs --vpc-ids vpc-0abc \
  --query 'Vpcs[0].DhcpOptionsId' --output text | \
xargs -I{} aws ec2 describe-dhcp-options --dhcp-options-ids {}
Fix 3

Create clients once, at module scope, so lookups are not repeated per invocation

A client constructed inside the handler resolves its endpoint on every invocation. Hoisting it to module scope means one lookup per execution environment instead of one per request, which removes most of the DNS load a high-concurrency function generates.

jsimport { SecretsManagerClient } from "@aws-sdk/client-secrets-manager";

// Module scope: resolved once per execution environment, reused across invocations.
const client = new SecretsManagerClient({});

export const handler = async (event) => {
  // Not: new SecretsManagerClient({}) on every request.
  return client.send(command(event));
};
Fix 4

Use a VPC endpoint so the call never needs public DNS

An interface endpoint for the service places it inside your VPC with a private DNS name, removing both the resolution and the routing problem in one change.

yamlSecretsManagerEndpoint:
  Type: AWS::EC2::VPCEndpoint
  Properties:
    VpcId: !Ref Vpc
    ServiceName: !Sub "com.amazonaws.${AWS::Region}.secretsmanager"
    VpcEndpointType: Interface
    PrivateDnsEnabled: true
    SubnetIds: !Ref PrivateSubnets

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.

getaddrinfo EAI_AGAINsocket.gaierror: [Errno -3] Temporary failure in name resolutionTemporary failure in name resolutionlambda eai_againlambda dns timeout vpc

Errors that show up alongside this one, or that people mistake for it.

References

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.