Aurora SSL + URL-Encoded Password Fix¶
Problem¶
After migrating to encrypted Aurora Serverless v2, the API Lambda (Node.js/Hono) returned {"status":"unhealthy","checks":{"database":"disconnected"}} while the migrator Lambda (Python/psycopg2) connected fine.
Symptoms¶
- Health endpoint: 503 with
database: disconnected - Plate lookup: 500
- API docs (no DB): 200 OK
- Migrator Lambda: connects and runs migrations successfully
- Same
DATABASE_URL, same VPC, same security group
Root Cause¶
Two issues combined:
1. Unencoded Password in DATABASE_URL¶
SST generates random passwords for Aurora clusters. These passwords can contain characters like :, #, ?, ) that break URL parsing. The Node.js pg library parses the connection string as a URL, causing the password to be truncated at the first special character.
Example: postgresql://postgres::#tT4...?:pI)@host:5432/reggie
- Python's
psycopg2handles this (more tolerant URL parser) - Node.js
pgdoes not (standard URL parser,#starts fragment,?starts query)
2. SSL Required but Not Configured Correctly¶
Encrypted Aurora clusters require SSL connections. The pg_hba.conf entry rejects non-SSL connections with: no pg_hba.conf entry for host ... no encryption.
The fix: ssl: { rejectUnauthorized: false } in the pg Pool config (RDS CA certs not in Node.js trust store).
Solution¶
URL-Encode Password in sst.config.ts¶
const encodedPassword = $resolve([db.password]).apply(([pw]) =>
encodeURIComponent(pw),
);
const databaseUrl = $interpolate`postgresql://${db.username}:${encodedPassword}@${writerHost}:${db.port}/${db.database}`;
SSL in services/api-ts/src/db/index.ts¶
Prevention¶
- Always URL-encode passwords in database connection strings
- Test database connectivity after any infrastructure change (not just migration success)
- The smoke test (
scripts/smoke-test.sh) checks/healthwhich validates DB connectivity
Related¶
- SST issue:
python.containerwraps Dockerfiles, breaking pip install - CI builds migrator Docker image directly to work around this