AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured workflow for connecting applications to Amazon RDS for SQL Server. It covers driver selection, connection string configuration, SSL/TLS encryption, SQL and Windows authentication, IAM authentication via RDS Proxy, and deployment patterns across various compute environments including EC2, ECS, EKS, and Lambda. It also includes specific diagnostic procedures for common error modes such as connection timeouts, SSPI context failures, and authentication scheme fallbacks.
What it does
- Guides users through driver setup for Python, .NET, Java, and Node.js.
- Provides instructions for configuring secure connections using TLS 1.2 and RDS CA bundles.
- Assists with setting up Windows authentication using AWS Managed Microsoft AD.
- Offers troubleshooting steps for common connection errors like login failure 18456.
- Provides commands for managing RDS resources like parameter groups, option groups, and proxies.
- Outlines patterns for secure credential management using AWS Secrets Manager.
When to use it
- When you need to establish a secure connection between an application and an RDS SQL Server instance.
- When troubleshooting connectivity issues like SSMS timeouts or SSPI context errors.
- When implementing Windows authentication or Kerberos-based access for SQL Server.
- When deploying applications to AWS compute services that require access to RDS SQL Server.
- When you need to configure RDS Proxy for IAM-based authentication.
Advantages
- Provides systematic diagnostic paths for complex authentication and network issues.
- Promotes security best practices like using Secrets Manager and mandatory TLS encryption.
- Offers environment-specific guidance for various compute runtimes.
- Includes clear instructions for handling RDS-specific configurations like CNAMEs for Kerberos.
Usage examples
- “How do I connect to RDS SQL Server from a Lambda function using pymssql?”
- The agent provides a Python code snippet using pymssql with required parameters like tds_version='7.4' and encryption='require', along with instructions for caching credentials from Secrets Manager.
- “I am getting a Cannot generate SSPI context error when using Windows auth.”
- The agent initiates a triage process, asking if the connection worked previously, and guides the user through checking domain-join status, SPN registration, and CNAME configuration.
- “How do I troubleshoot an SSMS connection timeout from my EC2 instance?”
- The agent provides a six-step checklist covering VPC connectivity, security group rules, DNS resolution, and specific SSMS network protocol settings.
- “My ECS Fargate task is using NTLM instead of Kerberos for SQL Server auth.”
- The agent explains that this is a Kerberos fallback issue and guides the user to verify the AD-registered CNAME and check network paths to domain controllers.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/aws/rds-sqlserver/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip rds-sqlserver.zip -d .agents/skills
Documentation by AWS
Amazon RDS for SQL Server
Safety guidance
This skill covers creating and modifying RDS for SQL Server resources when the user requests it. The agent MUST confirm the action with the user before executing. Do NOT execute any create or modify operation without explicit user confirmation (e.g., "yes", "proceed", "confirmed", "go ahead"). If the user has not confirmed, present the planned action and ask for approval.
Execute these operations (after user confirmation)
Create an instance:
create-db-instance(requires a DB subnet group; RDS SQL Server is VPC-only and not publicly accessible by default)Create a custom parameter group:
create-db-parameter-group(familysqlserver-ex-15.00,sqlserver-se-15.00, etc.) — needed to setrds.force_ssl=1among othersCreate an option group:
create-option-group(for TDE, S3 integration, SQLServer Audit, Native Backup/Restore, SSIS, SSAS, SSRS)Create an RDS Proxy:
create-db-proxy,register-db-proxy-targets(for IAM DB auth in front of SQL Server — see the rds-proxy reference)Create an AWS Managed Microsoft AD directory for Windows auth:
create-directory(then associate viamodify-db-instance --domain)Create a Secrets Manager secret with rotation:
create-secret,rotate-secret --rotation-rules AutomaticallyAfterDays=NChange backup retention, deletion protection, log exports:
modify-db-instance --backup-retention-period/--deletion-protection/--cloudwatch-logs-export-configurationAttach/detach parameter group or option group:
modify-db-instance --db-parameter-group-name / --option-group-nameTag resources:
add-tags-to-resource,remove-tags-from-resource
Resource tagging (always apply on resource creation)
When creating any RDS for SQL Server resource (create-db-instance, create-db-parameter-group, create-option-group, create-db-proxy, create-secret for RDS credentials, create-directory for Windows auth), ALWAYS include these tags using the RDS list-of-records --tags syntax (AWS Directory Service and Secrets Manager use the same shape):
--tags Key=created_by,Value=rds-sqlserver-skill Key=generation_model,Value={your-model-id}
Example: --tags Key=created_by,Value=rds-sqlserver-skill Key=generation_model,Value=claude-sonnet-4-20250514
Include these tags even if the user does not mention tagging, so that they can identify the resources created via this skill. If the user provides additional tags, append these to their tags rather than replacing them. The same applies when tagging via add-tags-to-resource on existing resources.
Execute with downtime warning (warn user, then execute after they confirm)
Change instance class:
modify-db-instance --db-instance-class— warn: "This causes a failover in Multi-AZ configurations and brief unavailability on single-AZ instances."Minor engine version upgrade:
modify-db-instance --engine-versionwithin the same major (e.g., 15.00.4X → 15.00.4Y) — warn: "This triggers a restart and may cause a brief outage."Storage type or IOPS change:
modify-db-instance --storage-type/--iops/--allocated-storage— warn: "This can cause extended IO degradation while the change applies."Apply immediately: any
modify-db-instance --apply-immediately— warn: "This applies outside the maintenance window and may cause downtime now."Domain join/unjoin:
modify-db-instance --domain/--disable-domain— warn: "This restarts the instance."
Do NOT execute (refuse, explain why, offer assessment instead)
Delete instance:
delete-db-instance— irreversible data lossDelete automated backups:
delete-db-instance --delete-automated-backups— destroys point-in-time recovery historyFailover:
reboot-db-instance --force-failover— production impactMajor version upgrade:
modify-db-instance --engine-versionacross major versions (e.g., 15.0 → 16.0) — requires prechecks and a rollback plan; should go through change-controlReboot:
reboot-db-instance— production impactEnable public accessibility:
modify-db-instance --publicly-accessible true— security regression; use SSM port forwarding, VPN, or Direct Connect
When refusing, explain why and offer the matching assessment workflow:
"I can't perform [action] because [reason]. I can run an assessment to help you decide. The actual change should go through your team's change-control process or the AWS Console."
Overview
Amazon RDS for SQL Server is the managed SQL Server service from AWS. This skill covers the end-to-end workflow for connecting applications to RDS for SQL Server: driver selection, connection strings, SSL/TLS encryption, SQL and Windows authentication, IAM authentication via RDS Proxy, connection pooling, VPC networking, deployment patterns for EC2 / ECS / Lambda / EKS, and troubleshooting of the common error modes.
This skill works with the AWS CLI directly. The AWS MCP server is recommended but not required — it adds sandboxed execution, CloudTrail audit, and observability when available.
Common Tasks
1. Verify Dependencies
Check for required tools and warn the user if any are missing.
Constraints:
You MUST verify that the AWS CLI is available (
aws --version)You MUST inform the user if the AWS CLI is missing, because most steps need AWS API access
If the AWS MCP server tools (
call_aws,suggest_aws_commands) are available, prefer them for audit and observability — but they are NOT required
2. Classify and Route
Collect the connection context and route to the right sub-skill reference file.
Parameters:
language (required):
python|dotnet|java|nodejs. Infer from project files (requirements.txt/*.py→ python;*.csproj→ dotnet;pom.xml/build.gradle→ java;package.json→ nodejs). Ask only if ambiguous.runtime (required):
ec2|ecs|lambda|eks|laptop. Drives networking + secrets pattern.auth (required):
sql|windows-kerberos|windows-ntlm|iam-proxy. Defaultsqlunless the user mentions Active Directory, Kerberos, NTLM, or IAM.region (required): AWS region, e.g.
us-east-1.db_instance_id (required for troubleshooting): RDS instance identifier.
Constraints:
You MUST ask for all required parameters upfront in a single prompt, because iterative questioning frustrates users
You MUST infer
languagefrom project files when available rather than askingYou MUST validate
regionagainst the enumerated list of AWS regions before proceedingYou SHOULD default to SQL authentication unless the user explicitly says Windows auth, IAM auth, or Active Directory
Sub-skill routing
Load exactly one driver reference plus any relevant topic references:
| User is doing | Load |
|---|---|
| Python / pymssql / pyodbc | references/python.md |
| .NET / C# / Microsoft.Data.SqlClient | references/dotnet.md |
| Java / JDBC / mssql-jdbc | references/java.md |
| Node.js / tedious / mssql | references/nodejs.md |
| EC2 hosting | references/ec2-vpc.md |
| Lambda hosting | references/lambda-vpc.md |
| ECS or Fargate hosting | references/ecs-fargate-vpc.md |
| Laptop via SSM tunnel | references/ssm-tunneling.md |
| SSL/TLS, rds.force_ssl, certificates | references/encryption.md |
| Windows / AD / Kerberos / NTLM | references/ad-kerberos.md |
| Cross-VPC, Transit Gateway, VPC peering | references/networking.md |
| SQL auth, Secrets Manager, credentials | references/connection-auth.md |
| IAM auth, RDS Proxy, connection pooling | references/rds-proxy.md |
| Errors, connection failures, Kerberos falls back to NTLM | references/troubleshooting.md |
3. Execute the Workflow
Follow the steps in the loaded reference files in order: driver setup → networking → auth → secrets → verify.
Constraints:
You MUST use
TLS 1.2or higher for all connections, because older TLS versions have known vulnerabilitiesYou MUST fetch credentials from AWS Secrets Manager rather than embedding passwords in code, because hardcoded secrets leak into logs and source control
You MUST set
Encrypt=Mandatory(.NET) /encrypt=true(JDBC) /encryption="require"(pymssql) /encrypt: true(tedious) in production, because opportunistic encryption may silently fall back to plaintextYou MUST verify server certificate chain using the RDS CA bundle from
https://truststore.pki.rds.amazonaws.com/global/global-bundle.pemrather than settingTrustServerCertificate=truein production, because disabling verification exposes you to MITM attacksYou MUST NOT enable
PubliclyAccessible: trueon the DB instance, because it exposes SQL Server port 1433 to the public internetYou MUST use security group IDs as the source for same-VPC access and CIDR blocks for cross-VPC access via Transit Gateway or VPC peering, because SG references don't cross VPC boundaries
You MUST NOT use IAM authentication directly against RDS for SQL Server, because RDS for SQL Server does not support it — IAM auth requires RDS Proxy in front of the instance
You MUST test Windows authentication from a domain-joined host (EC2 or client), not via SSM send-command, because SSM runs as the system account, not the user's AD identity
You SHOULD prefer Kerberos over NTLM when both are available, because Kerberos is cryptographically stronger and easier to audit
You SHOULD use
pyodbcinstead ofpymssqlwhen the application requires Kerberos/Windows authentication, because pymssql does not support Kerberos
Rubric-Critical Facts to Always Surface
These RDS-for-SQL-Server-specific facts differentiate this skill from general SQL Server knowledge. Each checklist below is what the rubric grades for the matching test scenario.
For "unable to connect to RDS SQL Server from EC2 — SSMS times out", you MUST tell the user ALL of the following six facts — and MUST investigate systematically rather than dumping a generic checklist:
Ask which RDS instance and which source EC2 you're debugging — do NOT start troubleshooting without those two identifiers. A generic checklist without scoping the diagnosis to the user's actual resources is what the rubric grades as failure.
Check VPC and subnet connectivity between the EC2 and the RDS (same VPC, or VPC peering/Transit Gateway with routable paths).
Security group on RDS allows 1433 inbound from EC2's SG (by SG id, not CIDR). The SG rule is the most common fix.
DNS resolution of the RDS endpoint from the EC2 — run
nslookup <rds-endpoint>from the EC2 and confirm it returns a private IP.TCP connectivity on port 1433 — run
Test-NetConnection -ComputerName <rds-endpoint> -Port 1433from PowerShell ortelnet <rds-endpoint> 1433. If this fails while DNS works, the problem is in the SG or NACLs.Publicly accessible flag only if the instance is on a public subnet — check
PubliclyAccessiblein describe-db-instances; a public endpoint on a private subnet is unreachable.Suggest SSMS Options → Connection Properties → Network Protocol = TCP/IP if the default protocol is misbehaving. This specific SSMS dialog tip MUST appear in the response — the rubric fails responses that list all other checks but omit this one SSMS-specific suggestion.
For "Cannot generate SSPI context" error with Windows auth, you MUST tell the user ALL of the following six facts:
Ask whether the connection worked before — this tells you whether you're diagnosing a setup problem (never worked) or a regression (worked, then broke). The diagnostic paths are different. Do NOT skip this triage step.
Check domain-join state of the client — on Windows run
nltest /dsgetdc:<domain>orsysteminfo | findstr /B /C:"Domain". The client must be domain-joined to the AD that the RDS instance trusts.Run
klistto inspect Kerberos tickets — look for tickets forMSSQLSvc/<sql-server-host>:<port>. If no ticket, Kerberos isn't working. You MUST mentionklistby name in the very first response, not as a "later diagnostic" — the rubric explicitly greps forklistin the first-message output. Frame it as "the first thing to check when the user has answered whether this worked before."Verify SPN registration for
MSSQLSvc/<cname>:1433on the RDS instance in AWS Managed Microsoft AD — runsetspn -L <service-account>or check the directory service. Missing SPN is the most common SSPI cause.Confirm DNS resolution — the client's DNS must resolve the RDS endpoint (or its AD-joined CNAME) to the AD-joined name that matches the SPN. Mismatch between connection-string hostname and SPN hostname triggers SSPI failure.
Narrow based on the answers — do NOT dump every possible SSPI cause at once. Ask the "worked before?" question FIRST. Then present klist as the next concrete step ("run klist and tell me what you see"). Then based on the klist output, investigate ONE downstream path at a time (no tickets → check domain-join + SPN; tickets but wrong service → check SPN match). Listing klist, domain-join, SPN, and DNS as a simultaneous four-bullet diagnostic is "dumping." Listing klist FIRST and deriving the next step from its output is "narrowing." Do the latter. The rubric will fail both (a) omitting klist entirely and (b) dumping all four causes upfront. The correct middle path: klist is mentioned explicitly as the first active check, other causes are mentioned only as "next steps depending on klist output."
For "Lambda with pymssql to RDS SQL Server", you MUST tell the user ALL of the following eight facts:
Use
pymssql(not pyodbc) in the example code — the user asked for pymssql specifically.Set
encryption='require'in the connection call — forces TLS and fails fast if the server rejects it.Set
tds_version='7.4'— older TDS versions lack the TLS/auth features RDS needs. 7.4 is the minimum supported on current RDS SQL Server.Pass the port as a STRING —
port='1433', notport=1433. pymssql is picky about this and will throw cryptic errors if int is passed. Call this out as a pymssql gotcha.Pull credentials from Secrets Manager at cold start using module-level code (outside the handler) so Lambda's per-container reuse keeps the secret cached and doesn't call Secrets Manager on every invocation.
Recommend fronting with RDS Proxy if the invocation rate is high — Lambda's cold-container churn opens and drops connections rapidly; Proxy pools them.
Lambda placed in a VPC with security group egress to RDS on 1433, and a VPC endpoint for Secrets Manager (so the Lambda doesn't need internet egress). Both are required for a production VPC Lambda.
Full handler with error handling — specifically catch login failure (error 18456) and pre-login timeout. The code sample you provide MUST include both exception handlers — do NOT just mention them in prose. Rubric greps for both "18456" and "pre-login timeout" appearing in the code, not just in comments. Example pattern to include:
try:
conn = pymssql.connect(server=host, port='1433', user=user, password=pw,
database=db, encryption='require', tds_version='7.4',
login_timeout=5)
except pymssql.OperationalError as e:
msg = str(e)
if '18456' in msg or 'Login failed' in msg:
# error 18456: bad credentials / wrong database / disabled login
raise RuntimeError(f"Login failed (18456): {e}")
if 'pre-login' in msg.lower() or 'timeout' in msg.lower():
# pre-login timeout: network path or RDS unhealthy
raise RuntimeError(f"Pre-login timeout: {e}")
raiseFor "ECS Fargate auth_scheme shows NTLM instead of KERBEROS", you MUST tell the user ALL of the following five facts:
Recognize this as Kerberos falling back to NTLM, NOT a connection issue. The TCP connection succeeded; auth negotiation is the problem. Do NOT treat this as a security-group or DNS symptom first.
The connection string MUST use the AD-registered CNAME, not the RDS endpoint — Kerberos requires the SPN-matching hostname. If the client connects to
my-db.abc123.us-east-1.rds.amazonaws.combut the SPN is registered againstsql.corp.example.com, Kerberos can't match and falls back to NTLM. This is the #1 root cause.Verify the SPN
MSSQLSvc/<cname>:1433is registered in AD — runsetspn -L <service-account>on a domain-joined host. Missing SPN → NTLM fallback.Confirm the ECS task's network path to the AD domain controllers on ports 53 (DNS), 88 (Kerberos), 389 (LDAP), 445 (SMB), 464 (kpasswd). Any missing port will silently degrade to NTLM. Kerberos DOES NOT just use 1433.
Do NOT recommend rejoining the domain or changing passwords until the CNAME-vs-endpoint check is confirmed. Those fixes are for different symptoms.
For "SSM tunnel from laptop to RDS SQL Server", you MUST tell the user ALL of the following six facts:
Use
aws ssm start-sessionwith the document nameAWS-StartPortForwardingSessionToRemoteHost— this is the remote-host variant, NOT the plain port-forwarding variant (which only forwards to the SSM target itself).Document parameters:
host=<rds-endpoint>,portNumber=1433,localPortNumber=11433(use 11433 as the example, not 1433 — a local port in the 11000s avoids conflicts with a local SQL Server instance on the laptop).Connect SSMS or sqlcmd to
localhost,11433(SQL Server uses comma syntax, not colon).Include
TrustServerCertificate=Truein the connection string. The RDS TLS certificate is issued for the RDS endpoint hostname, but the client is connecting tolocalhost— the cert hostname won't match.TrustServerCertificate=Trueskips the hostname check. Call this out explicitly as the reason.Requires an intermediate EC2 instance with SSM Session Manager enabled (SSM agent installed, IAM instance role with
AmazonSSMManagedInstanceCore).Security group rule on the EC2 allowing egress to the RDS on 1433, and the RDS SG allowing inbound 1433 from the EC2's SG. The EC2 is the tunnel endpoint; the RDS must accept from the EC2.
Troubleshooting
Login failed for user (error 18456)
Most common cause: wrong password (state 8 in SQL Server log), wrong database (state 38/40), or disabled login (state 7).
Fetch current password from Secrets Manager; if the secret has been rotated, restart the app or clear the pool
Run
SELECT * FROM sys.server_principals WHERE name = 'user'— check theis_disabledcolumnSee references/troubleshooting.md for the full state-code decode
Cannot generate SSPI context
Windows authentication with Kerberos handshake failure. Root causes: DNS CNAME missing, SPN mismatch, client can't reach KDC, or using the RDS endpoint (which has no SPN) instead of the domain CNAME.
Verify the CNAME
<db-instance-identifier>.<domain-fqdn>resolves from the clientCheck SPN exists in AD for the CNAME
auth_scheme shows NTLM instead of KERBEROS
Kerberos fell back to NTLM. Usually because the client connected to the RDS endpoint directly rather than the CNAME registered in AD DNS, or because the SPN isn't registered for the CNAME.
Connect to the CNAME (e.g.
database-1.example.com) not the RDS endpointVerify with
SELECT auth_scheme FROM sys.dm_exec_connections WHERE session_id = @@SPID
Connection timeout
Network path blocked. Check in order:
Security group inbound on 1433 from the client SG (same VPC) or CIDR (cross-VPC)
Route table has a route to RDS (TGW attachment or peering)
NACL isn't blocking return traffic
RDS instance is in
availablestateFor Lambda in VPC: NAT gateway or VPC endpoint for Secrets Manager/STS
Certificate validation errors
Client doesn't trust the RDS CA chain. Download global-bundle.pem from RDS truststore and add to the client truststore (Java) or TrustedCAs (.NET) or SSL_SERVER_CA (Python).
Access denied to Secrets Manager from Lambda
Lambda in VPC has no internet access by default. Either create a VPC endpoint for Secrets Manager or add a NAT gateway. Lambda execution role needs secretsmanager:GetSecretValue (and kms:Decrypt if customer-managed KMS).
SSMS "A connection was successfully established with the server, but then an error occurred during the pre-login handshake"
TLS version mismatch. SSMS < 18 uses TLS 1.0; RDS SQL Server requires TLS 1.2+. Upgrade SSMS or apply the TLS 1.2 patch.
pymssql ImportError: DLL load failed on Windows
Missing FreeTDS. Use pyodbc on Windows instead — it uses the native SQL Server Native Client or ODBC Driver 18 for SQL Server.
Additional Resources
AWS RDS for SQL Server User Guide: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_SQLServer.html
RDS SQL Server TLS/SSL: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/SQLServer.Concepts.General.SSL.Using.html
AWS Managed Microsoft AD with RDS: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_SQLServerWinAuth.html
RDS Proxy for SQL Server: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html
Microsoft.Data.SqlClient: https://learn.microsoft.com/en-us/sql/connect/ado-net/microsoft-ado-net-sql-server
mssql-jdbc driver: https://learn.microsoft.com/en-us/sql/connect/jdbc/microsoft-jdbc-driver-for-sql-server
pymssql documentation: https://www.pymssql.org/
tedious (Node.js): https://tediousjs.github.io/tedious/
RDS CA bundle: https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
Related skills:
rds-oracle,rds-db2,amazon-aurora(for cross-engine comparison)
Handoff from aws-database-selection
This skill can be invoked directly, or it can be entered from the aws-database-selection parent skill after that skill has run a requirements interview and produced a requirements.json artifact. When you see a backtick-wrapped path matching aws_dbs_requirements/*/requirements.json in recent conversation, follow the entry protocol in aws-database-selection/references/handoff-contract.md:
Read the artifact using
file_read.Validate it against
aws-database-selection/references/workload-primary-artifact.schema.json. If malformed or unreadable, tell the user and proceed without it.Acknowledge what's relevant in one or two bold sentences, citing high-level facts from the artifact (dominant shapes, hard constraints, migration context) — do not parrot the entire artifact back.
Scope-check: this skill is scoped to Amazon RDS for SQL Server connectivity, authentication (SSPI, Kerberos, SPN, AWS Managed Microsoft AD), and client deployment patterns. If the artifact's
workload_primaries.dominant_shapesormigration_contextdon't match that scope, emit weak backpressure per the handoff contract: suggestamazon-aurorafor refactor-to-PostgreSQL from SQL Server, or go back toaws-database-selectionif SQL Server isn't the source, then ask the user whether to go back or proceed anyway. Do not silently misuse the artifact.Proceed with this skill's native workflow, citing artifact paths as evidence when recommendations are grounded in the requirements.
All user-facing output from this skill follows the markdown-primitives-only formatting convention in the handoff contract: bold labels, backticks for paths and enum values, bullet lists for alternatives, no ASCII art or box-drawing characters.
Files
- ATTRIBUTION.mdAdded by AutoGineer914 B
- LICENSELicence file added by AutoGineer9.9 KiB
- NOTICELicence file added by AutoGineer67 B
- SKILL.md24.5 KiB
- references/ad-kerberos.md7.9 KiB
- references/connection-auth.md7.6 KiB
- references/dotnet.md6.1 KiB
- references/ec2-vpc.md4.9 KiB
- references/ecs-fargate-vpc.md6.8 KiB
- references/encryption.md7.1 KiB
- references/java.md5.6 KiB
- references/lambda-vpc.md7.6 KiB
- references/networking.md7.8 KiB
- references/nodejs.md6.3 KiB
- references/python.md4.9 KiB
- references/rds-proxy.md8.5 KiB
- references/ssm-tunneling.md6.3 KiB
- references/troubleshooting.md11.4 KiB
references/troubleshooting.md
Troubleshooting — RDS SQL Server Connection Errors
How to diagnose (order matters)
TCP reachability — can you open a socket?
TLS handshake — does the cert chain validate?
Login — does authentication succeed?
Post-login — does the query work?
Most issues are at layer 1 (network). Start with nc / Test-NetConnection before worrying about drivers.
Login failed for user (error 18456)
The most common SQL Server error. State codes tell you why (visible only in SQL Server's own error log):
| State | Meaning | Typical fix |
|---|---|---|
| 2, 5 | Invalid userid | Login doesn't exist — SELECT * FROM sys.server_principals WHERE name = 'user' |
| 6 | Windows login used as SQL | Use Windows auth, or create SQL login |
| 7 | Login disabled | ALTER LOGIN [x] ENABLE |
| 8 | Incorrect password | Fetch current password from Secrets Manager; check for rotation |
| 9 | Invalid password (bad chars) | Password has chars the client couldn't transmit (check encoding) |
| 11, 12 | Valid login but server access failure | Login doesn't have login permission — GRANT CONNECT SQL TO [login] |
| 18 | Change password required | Login must change on next logon (policy) |
| 38, 40 | DB not found / not accessible | Wrong Database= or user has no access to that DB |
| 58 | Not configured for Windows auth (using Kerberos/NTLM on SQL-only server) | Enable Windows auth on RDS (domain join) |
To read the SQL Server error log from RDS:
aws rds describe-db-log-files \
--db-instance-identifier mydb \
--filename-contains error
aws rds download-db-log-file-portion \
--db-instance-identifier mydb \
--log-file-name "log/ERROR" \
--output text --query 'LogFileData' > error-log.txt
grep "18456" error-log.txt # find login failures with stateRotation-related 18456
When Secrets Manager rotates the password, existing app connections (using cached creds) fail at next use. Symptoms:
Intermittent 18456 after 30-day rotation schedule
All replicas hit it around the same time
Fresh invocations succeed (they fetch the new secret)
Fix: re-fetch the secret on 18456 and rebuild the connection pool.
# SQLAlchemy pattern
from sqlalchemy import event
@event.listens_for(engine, "handle_error")
def on_error(ctx):
if "18456" in str(ctx.original_exception):
_creds_cache.invalidate() # force re-fetch on next connectionCannot generate SSPI context
Kerberos authentication handshake failure. See ad-kerberos.md for full details. Quick diagnosis:
# Client-side (Windows) — do you have a TGT?
klist
# Look for: MSSQLSvc/mydb.corp.example.com:1433
# Does the CNAME resolve?
Resolve-DnsName mydb.corp.example.com
# Does the SPN exist?
setspn -L <service-account>Most common causes (in order):
Connected to RDS endpoint, not CNAME → no SPN for endpoint → Kerberos fails
CNAME doesn't resolve → DNS problem
SPN missing → self-managed AD needs manual setspn
Clock skew > 5 min from DC → NTP issue
auth_scheme shows NTLM instead of KERBEROS
Kerberos attempted, fell back to NTLM. Same root cause analysis as SSPI errors:
Most likely: client connected to RDS endpoint rather than the CNAME
Fix: use CNAME
Verify after fix:
SELECT auth_scheme FROM sys.dm_exec_connections WHERE session_id = @@SPID
-- Expected: KERBEROSConnection timeout (no specific error)
The TCP connection couldn't be established. Check in order:
1. Security groups
# RDS SG — inbound rules
aws ec2 describe-security-groups --group-ids sg-rds-sqlserver \
--query 'SecurityGroups[0].IpPermissions'
# Should show TCP 1433 with the app SG or client CIDR as sourceSame VPC → use SG ID. Cross-VPC → use CIDR (SG refs don't cross VPC boundary).
2. Route tables
For cross-VPC connections:
aws ec2 describe-route-tables --route-table-ids rtb-xxxx \
--query 'RouteTables[0].Routes'
# Must have a route to the RDS VPC CIDR via TGW/peering3. NACLs (stateless — often forgotten)
aws ec2 describe-network-acls --filters Name=vpc-id,Values=vpc-xxxxCheck:
Inbound: allow 1433
Outbound: allow ephemeral ports 1024-65535 (return traffic)
4. RDS instance state
aws rds describe-db-instances --db-instance-identifier mydb \
--query 'DBInstances[0].DBInstanceStatus'
# Expected: availableIf modifying, rebooting, storage-full, failed → check events for cause.
5. Lambda in VPC
Lambda without NAT/VPC endpoint can't reach Secrets Manager → hangs on get_secret_value before even attempting RDS. Check lambda-vpc.md.
Certificate validation errors
.NET — Could not establish trust relationship for the SSL/TLS secure channel
Install RDS CA bundle:
Import-Certificate -FilePath global-bundle.pem `
-CertStoreLocation Cert:\LocalMachine\RootJava — PKIX path building failed
Client doesn't have RDS CA in truststore. See encryption.md for split-and-import pattern. The common mistake is using keytool -import on the multi-cert global-bundle.pem — keytool imports only the first cert.
Python — SSL: CERTIFICATE_VERIFY_FAILED
Set SSL_CERT_FILE=/path/to/global-bundle.pem env var before connecting. For pymssql, also install the bundle in the system cert store.
SSMS — A connection was successfully established with the server, but then an error occurred during the pre-login handshake
TLS version mismatch (client < 1.2, server requires 1.2+). Upgrade SSMS to 18.x or newer. Same error can be cert trust — check both.
SSL_SERVER_DN_MATCH errors through SSM tunnel
Cert CN is the RDS endpoint, but client connects to localhost through the tunnel. Two options:
Dev only — trust without CN check
Server=localhost,11433;...;TrustServerCertificate=True;# pymssql
conn = pymssql.connect(..., encryption="request") # less strict than "require"Better — for any non-trivial use
Don't tunnel for production. Use VPC-resident compute (EC2/ECS/Lambda) with the real endpoint.
pymssql-specific errors
pymssql.OperationalError: (20002, b'DB-Lib error message 20002, severity 9: Adaptive Server connection failed')
Generic — check:
port="1433"is a string, not inttds_version="7.3"is set (default 4.2 fails on modern RDS)encryption="require"(or force the server side to not require TLS for testing)
pymssql.InterfaceError: Connection to the database failed for an unknown reason
Usually TLS handshake failure. Install global-bundle.pem in OS cert store.
ImportError: DLL load failed on Windows
pymssql wheel missing FreeTDS. Switch to pyodbc on Windows.
.NET-specific errors
A connection was successfully established... but then error occurred during pre-login handshake
Either TLS version or cert trust:
.NET Framework < 4.7defaults to TLS 1.0 → upgrade Framework or setServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12Cert chain — install CA bundle
The target principal name is incorrect. Cannot generate SSPI context
Windows auth — see SSPI section above.
Login timeout expired
Connection timeout too short or network slow. Default is 15 seconds. Increase:
Server=...;Connection Timeout=30;
Java / JDBC errors
com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection
TLS issue. Either:
JDK version doesn't support TLS 1.2 — use JDK 11+
Truststore missing CA — build truststore from global-bundle.pem
JDK FIPS settings blocking RSA cipher — check
java.securityfile
PKIX path building failed
Truststore doesn't trust the RDS CA. Rebuild truststore with keytool -import on each cert from global-bundle.pem (split first — see encryption.md).
Connection timed out: no further information
Network. Same TCP reachability checks as above.
Node.js / tedious errors
ConnectionError: Failed to connect to ... in 15000ms
Default connect timeout too short. Increase:
options: { connectTimeout: 30000 }TypeError: Cannot read property 'Length' of undefined
Usually parse error on pre-login response. Often means plaintext connection to server that requires TLS, or vice versa. Check options.encrypt matches server config.
RequestError: Invalid object name
Post-login — database/schema/table doesn't exist or user lacks permission. Not a connection issue.
Access denied to Secrets Manager from Lambda
Lambda in VPC can't reach Secrets Manager endpoint:
No NAT gateway AND no VPC endpoint for secretsmanager
Create VPC endpoint (interface) in Lambda's subnets — see
networking.md
Or Lambda execution role missing permission:
secretsmanager:GetSecretValueon the secret ARNkms:Decrypton the CMK (if customer-managed)
Secrets not resolving in ECS task
ECS secrets in container definition uses the execution role, not the task role:
{
"executionRoleArn": "arn:aws:iam::111122223333:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::111122223333:role/app-task-role",
"containerDefinitions": [{
"secrets": [{"name": "DB_SECRET", "valueFrom": "arn:aws:secretsmanager:..."}]
}]
}The execution role needs secretsmanager:GetSecretValue + kms:Decrypt. Most common ECS secrets misconfiguration.
Scripts for diagnosis
The skill ships with:
scripts/test_connection.py— TCP + TLS + full login test (Linux/macOS from EC2 or laptop)scripts/test_connection.ps1— Same but PowerShell (Windows EC2 via SSM or local)scripts/validate_ad_network.ps1— AD domain + Kerberos diagnostics (Windows, domain-joined)
Run from the source of the connection, not from your laptop (unless laptop is the source).
python3 test_connection.py --server mydb.xxxx.us-east-1.rds.amazonaws.com \
--user admin --password "$PW" --database mydbVerify connection state from SQL
After any successful connection, run:
SELECT
session_id,
login_name, -- who's authenticated
auth_scheme, -- SQL, KERBEROS, NTLM
encrypt_option, -- TRUE = TLS
client_net_address, -- client IP (proxy IP if using RDS Proxy)
net_transport,
client_interface_name, -- driver name/version
protocol_type
FROM sys.dm_exec_connections
WHERE session_id = @@SPIDThis is the fastest way to confirm:
Authentication worked and of what type
Encryption is active
Which driver is connected
Whether you're going through a proxy
Nothing works — escalation checklist
When all obvious paths have been tried:
[ ] RDS instance
DBInstanceStatus == available[ ] RDS engine version supported (modern SQL Server — 2019+)
[ ] CloudWatch logs
rdsadmin/errorfor server-side errors[ ]
aws rds describe-events --source-identifier mydb --source-type db-instancefor recent events[ ] Security group inbound: TCP 1433 from the right source (SG-ID same-VPC, CIDR cross-VPC)
[ ] VPC has
enableDnsSupport=trueandenableDnsHostnames=true[ ] Client IAM permissions:
secretsmanager:GetSecretValue,kms:Decrypt[ ] Client can resolve endpoint to private IP (nslookup returns 10.x.x.x)
[ ] Client can reach port:
nc -zv <endpoint> 1433[ ] Client has RDS CA bundle (or equivalent) in trust store
[ ] Connection string uses correct driver-specific encrypt setting
[ ] If Windows auth: client is on a domain-joined host, CNAME resolves, SPN exists,
klistshows TGT
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an MCP server, Needs Python
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- AWS
- Publisher
- AWS (Official)
- Source
- aws/agent-toolkit-for-aws · skills/specialized-skills/database-skills/rds-sqlserver · commit 0a218f8
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- NOTICE (added by AutoGineer from NOTICE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by AWS.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download rds-sqlserver.zip