Problem Description
The inference service deployed on an AWS EC2 instance (private subnet) cannot establish a TCP connection to the remote RAG vector store (Milvus, Pinecone, or Qdrant). Every request to retrieve relevant documents ends with a timeout, causing the entire inference pipeline to fail.
Typical log excerpts:
2024-09-10T12:34:56.123Z ERROR langchain.vectorstores.milvus: connect ETIMEDOUT 172.31.45.23:443
2024-09-10T12:34:57.001Z ERROR pinecone.client: Request timed out after 30000ms
2024-09-10T12:35:01.045Z ERROR milvus: SSLHandshakeException: Remote host closed connection during handshake
2024-09-10T12:35:02.210Z ERROR qdrant: AuthenticationError: Invalid API key
Impact includes:
- 100 % request failures for downstream API consumers.
- Increased latency metrics and alarm fatigue.
- Potential SLA breach for RAG‑enabled applications.
Root Cause Analysis
Multiple layers can block connectivity from EC2 to a vector store. The most common causes, corroborated by the evidence package, are:
- Network path blockage – security‑group egress rules, NACLs, or missing route to a NAT gateway/VPC endpoint. A real incident reported that a security‑group change denying outbound
443/tcpcaused 100 % timeouts to a Milvus cluster. - VPC routing misconfiguration – asymmetric routing due to incorrect VPC peering or missing route table entries. The “Misconfigured VPC peering” incident showed SSL handshake failures and “Network is unreachable” errors.
- Authentication failures – expired or missing API keys, or insufficient IAM permissions for PrivateLink endpoints. The Pinecone client issue highlighted missing
iam:PassRolepermissions after moving the service to a private subnet. - Idle‑timeout limits on NAT gateways – NAT gateways enforce a 5‑minute idle timeout. A production fleet experienced periodic
ETIMEDOUTwhen the inference service kept idle connections to a hosted Pinecone instance.
In most cases, the immediate error connect ETIMEDOUT 172.31.x.x:443 points to an outbound network block (security group or route). Subsequent SSL or authentication errors appear once the TCP path is restored but TLS or credential validation fails.
Investigation and Debugging Steps
1. Verify basic network reachability
# From the EC2 instance shell
nc -zv vector-store.example.com 443
# Expected output:
# Connection to vector-store.example.com 443 port [tcp/https] succeeded!
If the command hangs or returns Connection timed out, the problem is at the network layer.
2. Inspect security‑group and NACL rules
# List SG attached to the instance
aws ec2 describe-instances --instance-ids i-0abcd1234efgh5678 \
--query 'Reservations[0].Instances[0].SecurityGroups[*].GroupId' --output text
# Describe egress rules
aws ec2 describe-security-groups --group-ids sg-0123abcd \
--query 'SecurityGroups[0].IpPermissionsEgress'
Ensure an egress rule allowing tcp port 443 to the vector‑store CIDR or 0.0.0.0/0.
3. Check route tables and NAT/PrivateLink configuration
# Show route table for the subnet
aws ec2 describe-route-tables --filters Name=association.subnet-id,Values=subnet-0a1b2c3d \
--query 'RouteTables[0].Routes'
# Example expected route entry for NAT gateway
# {
# "DestinationCidrBlock": "0.0.0.0/0",
# "GatewayId": "nat-0a1b2c3d4e5f6g7h8"
# }
If the vector store resides in another VPC, verify VPC peering or PrivateLink endpoint routes as described in the AWS VPC Documentation.
4. Validate TLS certificates and client configuration
# Retrieve the server certificate chain
openssl s_client -connect vector-store.example.com:443 -showcerts
Missing intermediate certificates or a mismatch between the server’s certificate and the client’s trust store will surface as SSLHandshakeException.
5. Confirm authentication credentials
# Example: Pinecone API key environment variable
echo $PINECONE_API_KEY
# Verify key length (should be 32+ characters)
[[ ${#PINECONE_API_KEY} -ge 32 ]] && echo "Key looks valid" || echo "Key missing/short"
Check IAM role policies if the vector store is accessed via AWS PrivateLink. The Instance Profiles documentation lists required iam:PassRole and execute-api:Invoke permissions.
6. Capture packet traces (optional)
sudo tcpdump -i eth0 host vector-store.example.com and port 443 -w /tmp/trace.pcap
# After reproducing the timeout, stop with Ctrl-C and analyze in Wireshark.
Solution
Network Fixes
Below is a before/after comparison of the security‑group configuration that caused the outage.
Before (outbound 443 denied):
{
"GroupId": "sg-0bad1234",
"IpPermissionsEgress": [
{
"IpProtocol": "tcp",
"FromPort": 80,
"ToPort": 80,
"IpRanges": [{ "CidrIp": "0.0.0.0/0" }]
}
// No rule for port 443
]
}
After (add egress 443 rule):
aws ec2 authorize-security-group-egress \
--group-id sg-0bad1234 \
--protocol tcp \
--port 443 \
--cidr 0.0.0.0/0
Result: nc -zv vector-store.example.com 443 now succeeds.
Routing Adjustments
If the vector store lives in a separate VPC, create a VPC peering connection and update route tables:
# Create peering
aws ec2 create-vpc-peering-connection \
--vpc-id vpc-0inference \
--peer-vpc-id vpc-0vectorstore
# Accept peering (in peer account)
aws ec2 accept-vpc-peering-connection --vpc-peering-connection-id pcx-0123abcd
# Add route to inference subnet
aws ec2 create-route \
--route-table-id rtb-0inference \
--destination-cidr-block 10.20.30.0/24 \
--vpc-peering-connection-id pcx-0123abcd
Authentication Corrections
For Pinecone accessed via PrivateLink, attach an IAM role with the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"execute-api:Invoke",
"iam:PassRole"
],
"Resource": "arn:aws:execute-api:*:*:pinecone/*"
}
]
}
Then, ensure the instance profile is associated with the EC2 instance:
aws ec2 associate-iam-instance-profile \
--instance-id i-0abcd1234efgh5678 \
--iam-instance-profile Name=InferenceServiceRole
Mitigating NAT Idle‑Timeout
Switch long‑lived connections to use a keep‑alive interval shorter than 4 minutes, or replace the NAT gateway with a Transit Gateway that does not enforce the 5‑minute idle limit.
Verification
After applying the fixes, run the following checks:
- Network reachability:
nc -zv vector-store.example.com 443 # Should output: succeeded! - TLS handshake:
openssl s_client -connect vector-store.example.com:443 -servername vector-store.example.comLook for
Verify return code: 0 (ok). - Application‑level request:
python - <<'PY' from langchain.vectorstores import Milvus vs = Milvus(host="vector-store.example.com", port=443, ssl=True) print(vs.similarity_search("test query")) PYExpect a JSON array of retrieved documents rather than a timeout exception.
- Metrics & alerts:
- Confirm
http_5xxcounters drop to zero in CloudWatch. - Validate latency
p95returns to baseline (< 200 ms).
- Confirm
Operational Best Practices & Prevention
- Guardrail security groups: Use a baseline SG that always allows outbound
443/tcpfor services that need external HTTPS. - Infrastructure as Code: Store SG, route table, and IAM role definitions in Terraform or CloudFormation. Include
aws_security_group_ruleresources withdescriptionfields to avoid accidental deletions. - Health‑check Lambda: Deploy a scheduled Lambda that attempts a TLS handshake to the vector store and publishes a custom CloudWatch metric. Alert on consecutive failures.
- Credential rotation automation: Use AWS Secrets Manager to store API keys and inject them via
ecs:secretorssm:GetParameters. Rotate automatically and trigger a rolling restart of inference containers. - Network topology documentation: Maintain an up‑to‑date diagram of VPC peering, PrivateLink endpoints, and NAT gateways. Include CIDR blocks to quickly spot routing gaps.
Related Topic Hub: Cloud Infrastructure Troubleshooting Hub
FAQ
- Why does the timeout only appear after a security‑group change?
Because outbound traffic on port 443 is blocked, the TCP SYN never receives a SYN‑ACK, leading the client library to emitconnect ETIMEDOUT. Once the rule is restored, the connection succeeds. - Can I use a VPC endpoint instead of a NAT gateway for a hosted Pinecone instance?
Yes. Pinecone supports AWS PrivateLink. Create a VPC endpoint for the service, update the route table to point to the endpoint, and ensure the instance role hasexecute-api:Invokepermissions. - How do I differentiate between a TLS handshake failure and an authentication error?
TLS failures appear asSSLHandshakeExceptionorRemote host closed connection during handshake. Authentication errors are raised by the client library after a successful TLS handshake, e.g.,AuthenticationError: Invalid API key. - What is the recommended idle timeout for long‑running inference calls?
Set the client’s HTTP keep‑alive to180 seconds(or less than the NAT gateway’s 300‑second limit) and configure the server to accept the same interval. - Do I need IAM permissions when connecting to an external vector store over HTTPS?
Only if you access the store via an AWS PrivateLink endpoint that uses IAM authentication (e.g., Pinecone PrivateLink). Otherwise, the service relies on API keys passed as headers or query parameters.