TL;DR
EC2 can't reach EFS port 2049 (NFS). Nine times out of ten it's the security group โ the EFS mount target's SG doesn't allow inbound NFS from the EC2. Add one rule: Type: NFS, Port: 2049, Source: your EC2's security group ID. Done.
What the error looks like
$ sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport fs-xxxxxxxx.efs.ap-northeast-1.amazonaws.com:/ /mnt/efs
mount.nfs4: Connection timed out
Or with the EFS mount helper:
$ sudo mount -t efs fs-xxxxxxxx:/ /mnt/efs
mount.nfs4: Connection timed out
The command hangs for 60โ90 seconds, then dies. No auth error, no "permission denied" โ just a clean timeout. That's your clue. A permissions failure rejects immediately. A timeout means the TCP connection never got through at all.
Root cause
EFS speaks NFS over TCP port 2049. When you run mount, the EC2 opens a TCP connection to the mount target's IP on that port. Drop that packet anywhere along the path and you get this timeout.
The usual suspects, ordered by how often they're the actual culprit:
- EFS security group missing inbound NFS rule โ the mount target's SG doesn't allow port 2049 from the EC2's SG (accounts for ~80% of cases)
- No mount target in the EC2's AZ โ EFS mount targets are per-AZ; if your EC2 is in
ap-northeast-1cbut the only mount target is inap-northeast-1a, it can't connect - Network ACL blocking traffic โ a NACL denying port 2049 inbound or the ephemeral port range (1024โ65535) outbound
- Different VPCs without peering โ EFS mount targets are VPC-local; cross-VPC access requires VPC peering configured on both sides
Fix: Security group (most likely)
Step 1 โ Find the EFS mount target's security group
# Replace with your filesystem ID and region
aws efs describe-mount-targets \
--file-system-id fs-xxxxxxxx \
--region ap-northeast-1
# Then get the security groups for a specific mount target
aws efs describe-mount-target-security-groups \
--mount-target-id fsmt-xxxxxxxx \
--region ap-northeast-1
Step 2 โ Get the EC2's security group ID
aws ec2 describe-instances \
--instance-ids i-xxxxxxxx \
--query 'Reservations[0].Instances[0].SecurityGroups' \
--region ap-northeast-1
Step 3 โ Add the inbound NFS rule
# sg-efs-id = security group on your EFS mount target
# sg-ec2-id = security group on your EC2 instance
aws ec2 authorize-security-group-ingress \
--group-id sg-efs-id \
--protocol tcp \
--port 2049 \
--source-group sg-ec2-id \
--region ap-northeast-1
Source by security group ID, not CIDR. That way the rule covers every instance in that SG automatically โ IPs change, group membership doesn't.
Fix: Missing mount target in the right AZ
Mount targets are per-AZ. An EC2 in ap-northeast-1a needs a mount target specifically in ap-northeast-1a. Check what you've got:
aws efs describe-mount-targets \
--file-system-id fs-xxxxxxxx \
--region ap-northeast-1 \
--query 'MountTargets[*].{AZ:AvailabilityZoneName,State:LifeCycleState,IP:IpAddress}'
Then confirm which AZ the EC2 is in:
aws ec2 describe-instances \
--instance-ids i-xxxxxxxx \
--query 'Reservations[0].Instances[0].Placement.AvailabilityZone' \
--region ap-northeast-1
No match? Create a mount target for the missing AZ โ either via the EFS console (Network tab โ Manage โ Add mount target) or CLI:
aws efs create-mount-target \
--file-system-id fs-xxxxxxxx \
--subnet-id subnet-xxxxxxxx \
--security-groups sg-efs-id \
--region ap-northeast-1
New mount targets take about 30โ60 seconds to reach available state. Don't retry the mount until it does.
Fix: Network ACLs
NACLs are stateless โ unlike security groups, they don't track connections. You need explicit rules for both directions.
# Find the subnet the EFS mount target lives in
aws efs describe-mount-targets \
--file-system-id fs-xxxxxxxx \
--query 'MountTargets[*].SubnetId'
# Check the NACLs on that subnet
aws ec2 describe-network-acls \
--filters Name=association.subnet-id,Values=subnet-xxxxxxxx \
--region ap-northeast-1
Look for a DENY rule that fires before the ALLOW for port 2049 inbound. Also check that ephemeral ports (1024โ65535) are allowed outbound โ return traffic from EFS uses those ports.
Verification
Test connectivity first
# From the EC2 โ check if port 2049 is reachable before mounting
nc -zv fs-xxxxxxxx.efs.ap-northeast-1.amazonaws.com 2049
# If fixed, you'll see:
# Connection to fs-xxxxxxxx.efs.ap-northeast-1.amazonaws.com 2049 port [tcp/nfs] succeeded!
nc still timing out? The network block is still there. Fix that first โ there's no point retrying mount until nc passes.
Mount and verify
# Install EFS mount helper (Amazon Linux 2)
sudo yum install -y amazon-efs-utils
# Mount with TLS via the helper
sudo mkdir -p /mnt/efs
sudo mount -t efs -o tls fs-xxxxxxxx:/ /mnt/efs
# Confirm it's mounted
df -h /mnt/efs
# Expected: fs-xxxxxxxx.efs.ap-northeast-1.amazonaws.com:/ ... 0% /mnt/efs
# Quick smoke test
echo "efs works" | sudo tee /mnt/efs/test.txt
cat /mnt/efs/test.txt
Persist across reboots
# Add to /etc/fstab
fs-xxxxxxxx:/ /mnt/efs efs defaults,_netdev,tls 0 0
The _netdev flag tells the OS to wait for network interfaces before mounting. Without it, the boot sequence tries to mount EFS before the network is up โ and fails silently, leaving /mnt/efs empty with no error logged.
Quick checklist
- EFS SG has inbound TCP 2049 from EC2 SG โ
- Mount target exists in the same AZ as the EC2 โ
- Mount target state is
available, notcreatingโ - EC2 and EFS are in the same VPC โ
- No NACL denying port 2049 or ephemeral ports (1024โ65535) โ
nc -zv <efs-dns> 2049succeeds before retrying mount โ

