Report this

What is the reason for this report?

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:

  • Downloaded the CA cert (digitalocean-ca.crt) from the database “Connection” page.
  • Placed it in ./certs/digitalocean-ca.crt in my repo.
  • In my 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);
  • Verified the cert path exists during runtime (logged with fs.existsSync()).
  • DATABASE_URL is clean (no sslmode=disable or ?ssl=false I am using sslmode=enable).
  • When I change to 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.

  • If we cannot disable this requirement, how do I fix this issue in my app? I am tired of trying to resolve this, I am stuck not able to log in to my test app because of this.

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!

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

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:

https://www.digitalocean.com/community/questions/how-to-add-ssl-certificate-to-app-platform-environment-variables-in-order-to-connect-to-managed-database

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

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.