AWS EC2 inference service connection timeout to RAG vector store

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:

  1. 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/tcp caused 100 % timeouts to a Milvus cluster.
  2. 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.
  3. Authentication failures – expired or missing API keys, or insufficient IAM permissions for PrivateLink endpoints. The Pinecone client issue highlighted missing iam:PassRole permissions after moving the service to a private subnet.
  4. Idle‑timeout limits on NAT gateways – NAT gateways enforce a 5‑minute idle timeout. A production fleet experienced periodic ETIMEDOUT when 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:

  1. Network reachability:
    nc -zv vector-store.example.com 443
    # Should output: succeeded!
    
  2. TLS handshake:
    openssl s_client -connect vector-store.example.com:443 -servername vector-store.example.com 

    Look for Verify return code: 0 (ok).

  3. 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"))
    PY
    

    Expect a JSON array of retrieved documents rather than a timeout exception.

  4. Metrics & alerts:
    • Confirm http_5xx counters drop to zero in CloudWatch.
    • Validate latency p95 returns to baseline (< 200 ms).

Operational Best Practices & Prevention

  • Guardrail security groups: Use a baseline SG that always allows outbound 443/tcp for services that need external HTTPS.
  • Infrastructure as Code: Store SG, route table, and IAM role definitions in Terraform or CloudFormation. Include aws_security_group_rule resources with description fields 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:secret or ssm: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

  1. 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 emit connect ETIMEDOUT. Once the rule is restored, the connection succeeds.
  2. 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 has execute-api:Invoke permissions.
  3. How do I differentiate between a TLS handshake failure and an authentication error?
    TLS failures appear as SSLHandshakeException or Remote host closed connection during handshake. Authentication errors are raised by the client library after a successful TLS handshake, e.g., AuthenticationError: Invalid API key.
  4. What is the recommended idle timeout for long‑running inference calls?
    Set the client’s HTTP keep‑alive to 180 seconds (or less than the NAT gateway’s 300‑second limit) and configure the server to accept the same interval.
  5. 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.