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

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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