How to Fix RDS Connection Refused in AWS (EC2, Lambda, Local Machine)
If your application cannot connect to Amazon RDS, the cause is almost always one of four things: wrong endpoint or port, the DB instance is not in an available state, a security group blocking the connection, or no valid network path between the client and the database. This guide walks through a systematic fix for each scenario, whether you are connecting from EC2, Lambda, ECS/EKS, or your local machine.
Simple explanation
Think of connecting to RDS like knocking on a locked door in a building.
Connection timed out is when you knock and nobody answers. Your request went somewhere, but nothing came back. The packet was likely dropped by a security group, a NACL, or a missing route before it ever reached the database.
Connection refused is when someone opens the door and immediately says “no.” Something received your packet and actively rejected it. For RDS this usually means the instance is stopped or you connected to the wrong address.
Authentication failed means you got through the door, walked up to the desk, and the receptionist said “you’re not on the list.” The network path is fine; your credentials are wrong.
| Error | What it usually means | Where the failure likely is | First thing to check |
|---|---|---|---|
Connection timed out | Packet dropped, no reply | Security group, NACL, or missing route | RDS security group inbound rules |
No route to host | No network path at all | Different VPC, Lambda outside VPC, no peering | Client and RDS VPC membership |
Connection refused | Packet reached something that rejected it | DB stopped, wrong port, wrong endpoint | DB instance status and correct port |
password authentication failed | TCP worked; credentials did not | Username, password, or IAM auth config | Application credentials or IAM token |
Quick answer: 60-second checklist
Run through this before digging into individual steps. Most RDS connection problems fail one of these checks:
- Connecting to the correct RDS endpoint (DNS name, not an IP address, not the wrong cluster endpoint)
- Port matches the engine: MySQL/Aurora MySQL → 3306, PostgreSQL/Aurora PostgreSQL → 5432, SQL Server → 1433
- DB instance status is
available, not stopped, rebooting, or modifying - RDS security group has an inbound rule allowing the client’s security group or IP on the DB port
- Client and database are in the same VPC, or VPC peering / Transit Gateway is configured
- Lambda functions have VPC configuration. Without it, Lambda has no path to a private RDS instance
- Outside-VPC clients (laptop, CI runner) have a tunnel: Session Manager, bastion/SSH, VPN, or Direct Connect
-
PubliclyAccessible=trueis only relevant for clients outside the VPC. It does nothing for EC2, Lambda with VPC config, or ECS/EKS
How RDS connectivity works
A good mental model: your VPC is a private office building. RDS is a server room on an interior floor with no public-facing entrance. EC2 instances are workstations already inside the building. Your laptop is someone standing on the pavement outside.
RDS instances are placed inside a VPC using a DB subnet group: a set of subnets across multiple availability zones. The subnet group determines which subnets and AZs RDS can use for placement and Multi-AZ failover.
Private vs public access is controlled by the PubliclyAccessible flag:
PubliclyAccessible=false(the default for most creation methods): the RDS DNS endpoint resolves to a private IP only. There is no way to reach the instance from outside the VPC without a tunnel or VPN.PubliclyAccessible=true: the endpoint resolves to a public IP. This still requires the DB subnet to have a route to an internet gateway, plus a security group rule allowing the client’s IP.
Regardless of the public access setting, all inbound traffic is governed by two independent controls:
- Security groups are stateful and attached to the RDS instance. They must explicitly allow inbound from the client on the DB port. Security groups are like a bouncer who remembers everyone they let in: if the bouncer waves you through on the way in, they automatically wave you through on the way out. You only need to write an inbound rule.
- Network ACLs are stateless and attached to the subnet. Unlike security groups, they have no memory. Every packet is checked individually, both directions. You must write rules for inbound traffic on the DB port and outbound return traffic on ephemeral ports (1024–65535). Misconfigured NACLs are a common source of timeouts that security group inspection alone will not explain.
Always connect using the DNS endpoint, never an IP address. RDS Multi-AZ failover and Aurora endpoint routing both change which IP is active, so hardcoding an IP breaks silently during the next failover.
When to use this page
This guide covers the most common RDS connection scenarios:
- EC2, ECS, or EKS in the same VPC: the client and RDS are colocated in private networking. Connection problems here are almost always security group rules or NACLs.
- Lambda: Lambda runs outside the VPC by default. Without explicit VPC configuration on the function, it has no path to a private RDS instance regardless of what the security groups say.
- Local laptop or developer machine: outside the VPC entirely. You need a tunnel (Session Manager port forwarding or bastion/SSH) or a network-level path (VPN, Direct Connect) to reach a private endpoint.
- Cross-VPC or on-premises: clients in a different VPC or on-premises network reaching RDS via VPC peering, Transit Gateway, or AWS Direct Connect.
RDS connection refused vs timed out vs authentication failed
The error text tells you which layer to investigate before touching a single setting.
Connection timed out / no route to host:
FATAL: could not connect to server: Connection timed out
Is the server running on host "mydb.xyz.us-east-1.rds.amazonaws.com"
and accepting TCP/IP connections on port 5432?The TCP connection attempt received no reply. The packet was silently dropped: security group with no matching rule, NACL blocking traffic, missing route, or Lambda not in the VPC. The RDS instance may not know the connection was attempted.
Connection refused:
FATAL: could not connect to server: Connection refusedSomething received the TCP SYN and responded with RST, an active rejection. For RDS this typically means the instance is stopped or in a transitional state. Less common than timeout for network-layer problems because AWS security groups drop packets rather than reject them.
Authentication failed:
FATAL: password authentication failed for user "admin"The TCP connection succeeded and RDS is running. This is entirely a credentials or IAM authentication issue. Do not chase security groups and NACLs when you see this error. Check the username, password, database name, or IAM auth token depending on your auth method.
Read the full error message before opening the AWS console. “Connection timed out” and “password authentication failed” require completely different fixes. Jumping straight to security groups when the error is a credentials problem is the most common way to spend an hour going in circles.
Step-by-step troubleshooting
Work through these steps in order. The most common causes surface in steps 1 through 4.
1. Confirm endpoint, port, and engine
Always connect using the RDS DNS endpoint, never an IP address. Pull the correct values:
aws rds describe-db-instances \
--db-instance-identifier my-database \
--query 'DBInstances[0].{Endpoint:Endpoint.Address,Port:Endpoint.Port,Engine:Engine,Status:DBInstanceStatus}'Common port mismatches:
| Engine | Default port |
|---|---|
| MySQL / Aurora MySQL | 3306 |
| PostgreSQL / Aurora PostgreSQL | 5432 |
| SQL Server | 1433 |
| MariaDB | 3306 |
| Oracle | 1521 |
For Aurora clusters, use the cluster endpoint for writes and the reader endpoint for reads. Do not connect to individual instance endpoints for Aurora. They are not stable across failovers.
2. Check DB instance status
A stopped, rebooting, or modifying instance will not respond to connections:
aws rds describe-db-instances \
--db-instance-identifier my-database \
--query 'DBInstances[0].DBInstanceStatus'Wait for available before continuing. If status is modifying or rebooting, connection failures are expected until it settles.
3. Check RDS security groups
The security group attached to the RDS instance must have an inbound rule allowing traffic from your client on the database port. Find the group:
aws rds describe-db-instances \
--db-instance-identifier my-database \
--query 'DBInstances[0].VpcSecurityGroups'Check its inbound rules:
aws ec2 describe-security-groups \
--group-ids sg-0123456789abcdef0 \
--query 'SecurityGroups[0].IpPermissions'A correct rule references the client’s security group ID, not a CIDR range:
Type: PostgreSQL
Protocol: TCP
Port range: 5432
Source: sg-0abc123app ← the EC2 / Lambda / ECS security groupReferencing a security group ID means every resource in that group is covered automatically. No maintenance is needed when instances are replaced or scaled.
A rule like 10.0.1.0/24 becomes stale the moment an instance is replaced with a different IP or you resize the subnet. Use a security group reference instead. It covers all members automatically and is far easier to audit during an incident.
4. Check whether the client and database have a valid network path
EC2 and RDS must be in the same VPC for direct private connectivity. Confirm:
# RDS VPC
aws rds describe-db-instances \
--db-instance-identifier my-database \
--query 'DBInstances[0].DBSubnetGroup.VpcId'
# EC2 VPC
aws ec2 describe-instances \
--instance-ids i-1234567890abcdef0 \
--query 'Reservations[0].Instances[0].VpcId'Both must return the same VPC ID. If they differ, you need VPC peering or Transit Gateway, plus route table entries on both sides pointing traffic toward the peering connection.
ECS and EKS: Tasks and pods must be placed in the same VPC as RDS. The task or pod security group must be explicitly allowed in the RDS security group inbound rules, the same rule you would write for EC2. Neither ECS nor EKS needs public RDS access to reach a private database; the connection stays entirely within the VPC. Tasks and pods that already share the VPC with RDS do not need NAT gateways or internet-facing routes for database traffic.
5. Check subnets, route tables, and NACLs
Same-VPC traffic routes locally without any explicit route table entry. NACLs are the more common issue here.
Find the subnets RDS is deployed in:
aws rds describe-db-instances \
--db-instance-identifier my-database \
--query 'DBInstances[0].DBSubnetGroup.Subnets[*].[SubnetIdentifier,SubnetAvailabilityZone]'Get the NACL for the RDS subnet:
aws ec2 describe-network-acls \
--filters "Name=association.subnet-id,Values=subnet-0abc123"The NACL on the RDS subnet must allow:
- Inbound: TCP on the DB port (5432 or 3306) from the client subnet CIDR
- Outbound: TCP on ephemeral ports 1024–65535 to the client subnet CIDR (return traffic)
Security groups are stateful: once an inbound rule matches, the response is automatically permitted back out. NACLs have no memory of previous packets. You must write the return path explicitly. A missing outbound ephemeral port rule is one of the most common causes of connection timeouts that look perfectly fine from the security group side.
6. Check public access only if the client is outside the VPC
PubliclyAccessible is only relevant when the connecting client is outside the VPC. For EC2, Lambda with VPC config, ECS, or EKS — all running inside the VPC — this setting has no effect on connectivity.
Check the current setting:
aws rds describe-db-instances \
--db-instance-identifier my-database \
--query 'DBInstances[0].PubliclyAccessible'If it returns false, the endpoint resolves to a private IP address only. For temporary development access, you can enable it:
aws rds modify-db-instance \
--db-instance-identifier my-database \
--publicly-accessible \
--apply-immediatelyThree things must all be true simultaneously: the flag is set, the DB subnet has a route to an internet gateway, and the security group allows inbound from your client IP. The flag alone changes how the DNS endpoint resolves. It does not open a working network path by itself.
See connecting to RDS securely for the recommended production approach.
7. Check Lambda VPC configuration
Lambda functions run outside your VPC by default. Think of it as a contractor who works from home: they can reach public internet resources but have no badge to enter the office building where your database lives.
A Lambda function without VPC configuration has no path to a private RDS instance, regardless of what the security groups say.
aws lambda get-function-configuration \
--function-name my-function \
--query 'VpcConfig'If SubnetIds and SecurityGroupIds are empty, the function is not in any VPC. Add it:
aws lambda update-function-configuration \
--function-name my-function \
--vpc-config SubnetIds=subnet-0abc123,subnet-0def456,SecurityGroupIds=sg-0lambda789Then allow the Lambda security group in the RDS inbound rules:
aws ec2 authorize-security-group-ingress \
--group-id sg-0rds456 \
--protocol tcp \
--port 5432 \
--source-group sg-0lambda789Lambda with VPC config loses its default internet path. If the function also needs internet access, it must route through a NAT gateway. See serverless VPC access for the full networking model.
8. Check local-machine access path
Your laptop is outside the VPC. For a private RDS instance, use one of the following access patterns in order of preference:
No open ports, no SSH keys, full audit trail in CloudTrail. This is the preferred option for local access to private RDS instances.
1. Session Manager port forwarding
aws ssm start-session \
--target i-1234567890abcdef0 \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"host":["mydb.xyz.us-east-1.rds.amazonaws.com"],"portNumber":["5432"],"localPortNumber":["5432"]}'Connect your DB client to localhost:5432. See Session Manager for setup requirements and IAM permissions.
2. Bastion host / SSH tunnel
An EC2 instance in a public subnet with SSH access, forwarding a local port to RDS:
ssh -L 5432:mydb.xyz.us-east-1.rds.amazonaws.com:5432 ec2-user@bastion-public-ip -NThe bastion security group must allow SSH (port 22) from your IP. The RDS security group must allow the bastion’s security group on the DB port.
3. VPN or Direct Connect
If your organisation has an AWS Site-to-Site VPN or Direct Connect circuit to the VPC, your machine can reach private VPC resources directly once the tunnel is established.
Setting PubliclyAccessible=true is an option for short-term development access, not a production pattern. If you use it temporarily, restrict the security group to your specific IP and revert before deploying to production.
9. Check pending parameter-group or reboot-related changes
If you have recently changed RDS parameter group settings such as SSL enforcement, max_connections, or authentication plugins, some changes require a reboot before they take effect. Unexpected connection behavior after a configuration change often means modifications are still pending.
aws rds describe-db-instances \
--db-instance-identifier my-database \
--query 'DBInstances[0].PendingModifiedValues'If PendingRebootValues is non-empty, the change is staged but not applied. Schedule a maintenance window reboot. It causes a brief connection interruption, typically 30 to 60 seconds.
Common mistakes
- Using IP or CIDR rules where security group references are better. A rule like
10.0.1.0/24becomes stale the moment an instance is replaced or the subnet is resized. Reference the security group ID instead. It automatically covers every member of the group regardless of how instances change. - Forgetting NACL return traffic rules. Security groups handle return traffic automatically because they are stateful. NACLs are stateless and do not. If the NACL on the RDS subnet lacks an outbound rule for TCP ephemeral ports (1024–65535) back to the client subnet, return packets are dropped and the connection times out, even when the security group rules look correct.
- Testing from a laptop against a private endpoint. A private RDS endpoint resolves to an internal VPC IP. Without a Session Manager tunnel, bastion, VPN, or Direct Connect, there is no route from your machine to that address. No amount of security group editing will fix a missing network path.
- Confusing authentication failures for network failures. The error
password authentication failedmeans the TCP connection worked and RDS is healthy. Investigating security groups and NACLs for this error wastes time. Check credentials, the database name, or the IAM auth token instead. - Using the wrong endpoint or the wrong port. Aurora clusters have a cluster endpoint, a reader endpoint, and individual instance endpoints. Connecting to the reader endpoint for writes, or using port 3306 for a PostgreSQL instance, produces errors that look like network problems but are not.
- Assuming PubliclyAccessible=true is enough for external access. Three conditions must all be true: the flag is set, the DB subnet has a route to an internet gateway, and the security group allows inbound from the client IP. The flag alone changes DNS resolution but does not open a working path.
- Sending writes to a replica endpoint. If your application accidentally routes writes to the read replica endpoint, the database engine rejects them. Use the primary or cluster endpoint for all writes.
Summary
- Connection timed out means the packet was dropped somewhere: security group, NACL, or no route. Connection refused means active rejection: DB stopped or wrong port. Authentication failed means the network is fine but credentials are wrong.
- Check the RDS security group first. It must explicitly allow inbound from your client’s security group on the database port.
- NACLs are stateless. Allow both inbound on the DB port and outbound ephemeral return ports (1024–65535).
- Lambda must have VPC configuration to reach private RDS. Without it, Lambda has no path into your VPC.
- For local machine access, use Session Manager port forwarding or a bastion host rather than enabling public access on the database.
Frequently asked questions
Should I make my RDS instance publicly accessible?
Avoid it for production. PubliclyAccessible=true makes the endpoint resolve to a public IP, but you still need the DB subnet to route to an internet gateway and the security group to allow inbound from your IP. A better option for external access is Session Manager port forwarding or a bastion host. Your database never gets a public IP and the access path is fully audited.
Why can EC2 connect but my laptop cannot?
EC2 is inside the VPC with a direct network path to the RDS subnet. Your laptop is outside the VPC entirely. Without a VPN, Direct Connect, or PubliclyAccessible=true combined with the right subnet and security group setup, there is no route from your laptop to the private RDS endpoint.
Why can EC2 connect but Lambda cannot?
Lambda runs outside your VPC by default. Even if EC2 and RDS are in the same VPC with correct security group rules, Lambda needs its own VPC configuration. It must be assigned to the same VPC and subnets, with a security group the RDS security group allows inbound from.
Should my security group rule reference an IP address or another security group?
Reference the security group ID. An inbound rule that allows sg-0abc123 automatically covers every resource in that group, even after instances are replaced or the pool scales. IP-based rules break when instances change or Auto Scaling rotates the pool.
Can ECS or EKS reach a private RDS instance without public access?
Yes. ECS tasks and EKS pods run inside the VPC and can reach RDS over private networking. The RDS security group must allow inbound traffic from the task or pod security group on the database port. No public access is needed.