Hi all,
I’m deploying a Node.js app on DigitalOcean App Platform that connects to a DigitalOcean-managed PostgreSQL database. I’m using drizzle-orm
for database access.
I’m consistently getting this error during login/auth operations:
Error: self-signed certificate in certificate chain at /workspace/node_modules/pg-pool/index.js:45:11 ... code: 'SELF_SIGNED_CERT_IN_CHAIN'
#What I’ve already tried:
digitalocean-ca.crt
) from the database “Connection” page../certs/digitalocean-ca.crt
in my repo.db.ts
, I’m reading and injecting it like this:import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
import fs from 'fs';
import path from 'path';
const certPath = path.resolve(__dirname, '../../certs/digitalocean-ca.crt');
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: true,
ca: fs.readFileSync(certPath).toString(),
},
});
export const db = drizzle(pool);
fs.existsSync()
).sslmode=disable
or ?ssl=false
I am using sslmode=enable
).rejectUnauthorized: false
, everything works — but that’s insecure and not an option for production.So my question is: Firstly, why is there not an option to simply disable the SSL requirement? I don’t want the communication between the database server and my app to be secured. I’ve already set trusted apps, so it doesn’t need an SSL layer as well, in my opinion.
exact error
[AUTH] Login error after 80 ms: Error: self-signed certificate in certificate chain
[layerr-app-prod] [2025-06-26 05:39:58] at /workspace/node_modules/pg-pool/index.js:45:11
[layerr-app-prod] [2025-06-26 05:39:58] at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
[layerr-app-prod] [2025-06-26 05:39:58] at async file:///workspace/node_modules/drizzle-orm/node-postgres/session.js:83:22
[layerr-app-prod] [2025-06-26 05:39:58] at async DatabaseStorage.getUserByEmail (file:///workspace/dist/index.js:3306:22)
[layerr-app-prod] [2025-06-26 05:39:58] at async file:///workspace/dist/index.js:4786:20 {
[layerr-app-prod] [2025-06-26 05:39:58] code: 'SELF_SIGNED_CERT_IN_CHAIN'
Thanks in advance.
Aasim
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Hey Aasim,
When you attach a Managed PostgreSQL database to your App Platform service, DigitalOcean automatically injects the required environment variables, including DATABASE_URL
and DATABASE_CA_CERT
.
You can check out the answers from this thread a couple of years ago as well:
So instead of bundling the .crt
file in your repo and reading it from disk, just reference the injected DATABASE_CA_CERT
directly in your code:
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: true,
ca: process.env.DATABASE_CA_CERT,
},
});
This avoids filesystem issues and is the recommended approach for App Platform deployments.
As for disabling SSL: that’s not possible with DigitalOcean Managed Databases, SSL is always enforced, even for trusted apps.
- Bobby
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.