Skip to content

[Bug] Helm chart v3.0.0: externalPostgresql.ca sets DB_SSL_CA as file path but server/core/db.js expects base64 content, causing SSL connection failure #7942

@NGPixel

Description

@NGPixel

Discussed in #7939

Originally posted by mhorcajada February 25, 2026
Description
In Helm chart v3.0.0, when configuring an external PostgreSQL with SSL using externalPostgresql.ca, the chart injects the value as a file path into the DB_SSL_CA environment variable. However, the application code in server/core/db.js expects DB_SSL_CA to contain the raw base64 certificate content (without PEM headers), not a file path.
This results in UNABLE_TO_GET_ISSUER_CERT_LOCALLY error and the pod going into CrashLoopBackOff.

Environment:
Wiki.js version: 2.5.312
Helm chart version: 3.0.0
Kubernetes: v1.35.1
PostgreSQL: external, managed by CloudNativePG, SSL enabled

Steps to Reproduce

  1. Deploy Wiki.js with Helm chart v3.0.0 using external PostgreSQL with SSL:
nodeExtraCaCerts: "/etc/ssl/certs/vault/vault-ca.pem"

externalPostgresql:
  host: postgres-rw.postgres.svc.cluster.local
  port: 5432
  database: wiki_production
  username: wiki
  existingSecret: wiki-db-secret
  existingSecretKey: postgresql-password
  ssl: true
  ca: /etc/ssl/certs/vault/vault-ca.pem
  1. The chart injects DB_SSL_CA as a file path (confirmed via helm get manifest):
- name: DB_SSL_CA
  value: "/etc/ssl/certs/vault/vault-ca.pem"
  1. Pod crashes with:
Database Connection Error: UNABLE_TO_GET_ISSUER_CERT_LOCALLY undefined:undefined

Root Cause
In server/core/db.js, DB_SSL_CA is read as base64 content and split into 64-char chunks to reconstruct a PEM:

javascriptif (!_.isEmpty(process.env.DB_SSL_CA)) {
  const chunks = []
  for (let i = 0, charsLength = process.env.DB_SSL_CA.length; i < charsLength; i += 64) {
    chunks.push(process.env.DB_SSL_CA.substring(i, i + 64))
  }
  sslOptions = {
    rejectUnauthorized: true,
    ca: '-----BEGIN CERTIFICATE-----\n' + chunks.join('\n') + '\n-----END CERTIFICATE-----\n'
  }
}

When DB_SSL_CA contains /etc/ssl/certs/vault/vault-ca.pem, the code treats the path string as base64 content and constructs an invalid PEM certificate, causing the SSL verification to fail.

Expected Behavior
Either:

The chart should read the CA file content and inject it as base64 into DB_SSL_CA, OR
The code in db.js should check if DB_SSL_CA is a file path and read its content with fs.readFileSync

Workaround:
Use NODE_TLS_REJECT_UNAUTHORIZED: "0" via extraEnvVars (traffic is still encrypted, only certificate verification is disabled):

extraEnvVars:
  - name: NODE_TLS_REJECT_UNAUTHORIZED
    value: "0"

Update:
Workaround NODE_TLS_REJECT_UNAUTHORIZED: "0" also fails
Tested with both NODE_TLS_REJECT_UNAUTHORIZED: "0" and NODE_EXTRA_CA_CERTS set — the error persists.
The reason is in server/core/db.js: rejectUnauthorized: true is hardcoded in the ssl object passed directly to the pg module, which ignores the NODE_TLS_REJECT_UNAUTHORIZED environment variable entirely.

The only working workaround is ssl: false.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions