RDS for Oracle — Troubleshooting
Common Oracle connectivity errors and fixes. Pair with the networking.md, connection-auth.md, and compute-runtime references for deeper context.
Connection errors (ORA-*)
ORA-12170 — TNS: Connect timeout
Network can't reach RDS.
- RDS SG inbound on 1521 allows your source (SG id same-VPC, CIDR cross-VPC)
- RDS instance is
available:aws rds describe-db-instances --db-instance-identifier <id> --query 'DBInstances[0].DBInstanceStatus' - Same VPC or peering/TGW with route tables in both directions
- NACLs not blocking 1521 (or ephemeral return ports 1024-65535)
- On-prem: VPN/Direct Connect up
Test:
nc -zv <rds-endpoint> 1521
bash scripts/test_connectivity.sh <endpoint> 1521ORA-12541 — TNS: no listener
Wrong endpoint or port.
- Verify:
aws rds describe-db-instances --db-instance-identifier <id> --query 'DBInstances[0].Endpoint' - Don't use the instance ID as the hostname — use the full
*.rds.amazonaws.comendpoint - Check the custom port if
Portisn't 1521
ORA-12514 — service not known
Wrong SERVICE_NAME or SID.
- Correct DB name:
aws rds describe-db-instances --db-instance-identifier <id> --query 'DBInstances[0].DBName' - Try both:
(CONNECT_DATA=(SERVICE_NAME=ORCL))vs(CONNECT_DATA=(SID=ORCL)) - After failover, the listener may take a moment to re-register
ORA-12505 — SID not known
Using SID syntax when a Service Name is required (common for newer tools). Switch to:
(CONNECT_DATA=(SERVICE_NAME=ORCL))ORA-01017 — invalid username/password
- Verify Secrets Manager value:
aws secretsmanager get-secret-value --secret-id <name> --query SecretString --output text - Password rotation — fetch fresh creds
- Case-sensitive passwords (RDS setting)
- Special chars in password may need escaping in connection strings
ORA-28040 — no matching auth protocol
Client driver too old.
- Update to Oracle 21c+ thin drivers:
python-oracledb 6+,ojdbc1123.x,node-oracledb 6+, ODP.NET Core latest - Thin mode avoids this entirely
ORA-29024 — certificate validation failure (TLS)
Client doesn't trust RDS CA.
curl -o global-bundle.pem https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem- Python: set
wallet_locationto the directory containing the PEM - Java: split the bundle and import each cert (keytool imports only the first)
- .NET: add to OS trust store (
update-ca-certificates) - Over SSM tunnel:
SSL_SERVER_DN_MATCH = FALSE(cert CN won't matchlocalhost)
ORA-28860 — fatal SSL error
TLS version or cipher mismatch.
- RDS option group:
SQLNET.SSL_VERSION = 1.2 - Client supports TLS 1.2
- JDK 8u261+ for full cipher support
Driver-specific
Python — DPI-1047
Thick mode can't locate Oracle Client.
- Switch to thin mode (python-oracledb 6+ default). Most code paths don't need thick.
- If you need thick:
oracledb.init_oracle_client(lib_dir="/usr/lib/oracle/21/client64/lib") - Install
libaioon Linux
Python — DPY-6005 (thin-mode limitation)
Some operation isn't supported in thin mode. Usually Kerberos with in-memory tickets or Advanced Queuing. Switch to thick for just that code path, or find the thin-compatible equivalent.
Python — ModuleNotFoundError: oracledb
pip install oracledbJava — ClassNotFoundException: oracle.jdbc.driver.OracleDriver
Add ojdbc11 dependency:
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11</artifactId>
<version>23.4.0.24.05</version>
</dependency>Java — UCP Cannot get Connection from Datasource
Pool exhausted.
maxPoolSizetoo low for workload- Connections not returned (use try-with-resources)
- RDS
max_connectionsexceeded across all app instances — check CloudWatchDatabaseConnections
Secrets Manager — AccessDeniedException
- Role has
secretsmanager:GetSecretValueon the correct ARN (including the random suffix) - If KMS-encrypted with a customer-managed key: add
kms:Decryptpermission - VPC endpoint for Secrets Manager? Endpoint policy allows the role?
- From VPC with no internet: need VPC endpoint for Secrets Manager
Secrets Manager — timeout from Lambda/ECS/EKS
- Lambda in VPC: VPC endpoint or NAT gateway for Secrets Manager
- SG allows outbound 443 to Secrets Manager endpoint
Platform-specific
Lambda — cold start > 5s
- Use thin mode (no Oracle Client load)
- Initialize pool at module scope (outside handler), reused across warm invocations
- Provisioned concurrency for latency-sensitive workloads
- Keep memory reasonable (higher memory is faster but costlier; ENI attachment is fixed ~1-2s)
Lambda — too many RDS connections
Each Lambda instance has its own pool. High concurrency → many connections.
- Keep pool
maxsmall (1-2 per instance) - Set Lambda reserved concurrency to cap total instances
- Monitor RDS
DatabaseConnectionsCloudWatch metric - Total max = concurrency × pool max
ECS Fargate — secrets not injected
- Task execution role (not task role) has
secretsmanager:GetSecretValue - Secret ARN in task definition matches exactly (with random suffix)
- Subnets have NAT or VPC endpoint for Secrets Manager
- Thin mode preferred for containers — no Oracle Client in image
EKS — pod can't access Secrets Manager via IRSA
- OIDC provider associated with cluster
- ServiceAccount annotated with IAM role ARN
- IAM role trust policy allows the ServiceAccount
- Role has
secretsmanager:GetSecretValue - Pod spec:
serviceAccountName: <sa-name>
EKS — too many connections from scaled pods
- Pool
maxsmall (1-3 per pod) - HPA
maxReplicas × max≤ RDS capacity budget - Monitor
DatabaseConnections, set CloudWatch alarms
SSM port forwarding
TargetNotConnected
SSM agent not running, or missing IAM.
aws ssm describe-instance-information --filters "Key=InstanceIds,Values=<id>"— PingStatus should beOnline- IAM instance profile has
AmazonSSMManagedInstanceCore systemctl status amazon-ssm-agent
Tunnel up, Oracle connect times out
- EC2 SG outbound 1521 to RDS SG
- RDS SG inbound 1521 from EC2 SG
- From Pattern B (SSM shell):
nc -zv <rds-endpoint> 1521
Session Manager plugin not found
brew install --cask session-manager-pluginAddress already in use on local port
--parameters '{"host":["..."],"portNumber":["1521"],"localPortNumber":["11521"]}'Then connect to localhost:11521.
Kerberos
ORA-12631 — Username retrieval failed
klist— no ticket? Runokinit joedoe@REALMsqlnet.orahasSQLNET.AUTHENTICATION_SERVICES = (KERBEROS5PRE,KERBEROS5)SQLNET.KERBEROS5_CC_NAMEpoints to correct cache file- Windows SQL*Plus:
OSMSFT:for in-memory; SQL Developer: use file cache
ORA-01017 with Kerberos
DB user is UPPERCASE and
IDENTIFIED EXTERNALLY:CREATE USER "JOEDOE@AD.MYAWS.COM" IDENTIFIED EXTERNALLY; GRANT CREATE SESSION TO "JOEDOE@AD.MYAWS.COM"; SELECT username, authentication_type FROM dba_users WHERE username LIKE '%JOEDOE%';
kerberos-disabled status
- IAM role
rds-directoryservice-kerberos-access-roleexists withAmazonRDSDirectoryServiceAccess - Directory ID correct, RDS VPC reaches AD DNS
- Remove + re-add domain:
--domain ""then re-add with--domain <id>
"Cannot find KDC"
krb5.confrealm names UPPERCASE- KDC hostnames resolve:
nslookup ad.myaws.com - TCP/UDP 88 open to KDC
- On-prem AD: forest trust established and working
DNS / Route 53
CNAME not resolving
- PHZ associated with the correct VPC
- VPC
enableDnsSupportandenableDnsHostnamesboth enabled aws route53 list-resource-record-sets --hosted-zone-id <id>— record exists
On-prem can't resolve PHZ
- Route 53 Resolver inbound endpoints in the VPC
- On-prem DNS forwards the zone to Resolver endpoint IPs
- VPN/DX allows UDP/TCP 53
Connection pooling
Pool exhausted
maxtoo low for workload- Connections leak — use try-with-resources / context managers
wait_timeoutset so requests don't hang- Monitor CloudWatch
DatabaseConnections
Stale connections
Enable validation-on-borrow:
- python-oracledb: handles automatically
- Java UCP:
setValidateConnectionOnBorrow(true)+setSQLForValidateConnection("SELECT 1 FROM dual") - HikariCP:
setConnectionTestQuery("SELECT 1 FROM dual")
ORA-02396 — exceeded maximum idle time
RDS IDLE_TIME profile parameter is closing idle connections.
- Increase/remove
IDLE_TIMEon the DB user profile - Or set pool
timeoutshorter thanIDLE_TIMEso the pool recycles first
CMAN
cmctl startup fails
ORACLE_HOMEset correctlycman.oraexists at$ORACLE_HOME/network/admin/cman.ora- Validate:
cmctl validate - Port 1521 not in use:
netstat -tlnp | grep 1521
Clients can't connect through CMAN
- CMAN EC2 SG allows inbound 1521 from client source
- CMAN EC2 SG allows outbound 1521 to RDS SG
- RDS SG allows inbound 1521 from CMAN EC2 SG (not client SG)
- CMAN running:
cmctl show status -c CMAN - Client DSN points to CMAN IP, not RDS directly
ORA-12529 — connection rejected
Source IP not in an ACCEPT rule. Add the CIDR to RULE_LIST in cman.ora.
Quick scripts
Bundled in scripts/:
| Script | Use |
|---|---|
test_connectivity.sh <endpoint> [port] |
DNS + TCP reachability |
check_rds_status.sh <instance-id> |
Status, endpoint, SGs, encryption |
check_security_groups.sh <instance-id> [source] |
Validate SG rules |
test_oracle_connection.py <endpoint> <port> <service> <user> |
Full Python test |
check_ssl_status.sql |
Verify encryption on current session |