brianc/node-postgres · error · Error
Both useLibpqCompat and uselibpqcompat are set. Please use o
Error message
Both useLibpqCompat and uselibpqcompat are set. Please use only one of them.
What it means
Thrown by pg-connection-string's parse() when the caller passes the option { useLibpqCompat: true } AND the connection string itself also contains the query parameter uselibpqcompat=true. The library exposes two ways to opt into libpq-compatible SSL semantics, and having both active simultaneously is treated as a configuration conflict. The guard at index.js:102 explicitly checks options.useLibpqCompat && config.uselibpqcompat and throws so the intent is unambiguous.
Source
Thrown at packages/pg-connection-string/index.js:103
}
// Only try to load fs if we expect to read from the disk
const fs = config.sslcert || config.sslkey || config.sslrootcert ? require('fs') : null
if (config.sslcert) {
config.ssl.cert = fs.readFileSync(config.sslcert).toString()
}
if (config.sslkey) {
config.ssl.key = fs.readFileSync(config.sslkey).toString()
}
if (config.sslrootcert) {
config.ssl.ca = fs.readFileSync(config.sslrootcert).toString()
}
if (options.useLibpqCompat && config.uselibpqcompat) {
throw new Error('Both useLibpqCompat and uselibpqcompat are set. Please use only one of them.')
}
if (config.uselibpqcompat === 'true' || options.useLibpqCompat) {
switch (config.sslmode) {
case 'disable': {
config.ssl = false
break
}
case 'prefer': {
config.ssl.rejectUnauthorized = false
break
}
case 'require': {
if (config.sslrootcert) {
// If a root CA is specified, behavior of `sslmode=require` will be the same as that of `verify-ca`
config.ssl.checkServerIdentity = function () {}
} else {
config.ssl.rejectUnauthorized = falseView on GitHub (pinned to c5e8c9a57b)
Solutions
- Remove uselibpqcompat from the connection string / DATABASE_URL query parameters, keeping only the programmatic { useLibpqCompat: true } option.
- Alternatively, remove { useLibpqCompat: true } from your options/config object and rely solely on the connection-string parameter.
- Centralize SSL configuration in one place (either the connection string or the options object) and document the chosen approach so contributors do not re-add the other form.
Example fix
// before
const pool = new Pool({
connectionString: 'postgres://host/db?sslmode=require&uselibpqcompat=true',
useLibpqCompat: true,
});
// after (pick ONE)
const pool = new Pool({
connectionString: 'postgres://host/db?sslmode=require&uselibpqcompat=true',
});
// or
const pool = new Pool({
connectionString: 'postgres://host/db?sslmode=require',
useLibpqCompat: true,
}); Defensive patterns
Strategy: validation
Validate before calling
const { parse } = require('pg-connection-string');
function safeParse(connStr, options = {}) {
// Check the connection string for uselibpqcompat before parsing
const hasParam = /[?&]uselibpqcompat=/.test(connStr);
if (options.useLibpqCompat && hasParam) {
throw new Error(
'Conflict: remove uselibpqcompat from the connection string OR remove useLibpqCompat from options.'
);
}
return parse(connStr, options);
} Try / catch
try {
const config = parseIntoClientConfig(connStr, { useLibpqCompat: true });
} catch (err) {
if (/useLibpqCompat and uselibpqcompat/i.test(err.message)) {
// Strip the duplicate from the connection string and retry without the option
const cleaned = connStr.replace(/([?&])uselibpqcompat=[^&]*/i, '$1');
config = parseIntoClientConfig(cleaned);
} else {
throw err;
}
} Prevention
- Standardize on exactly one libpq-compat activation method (connection-string param OR options object) and document it in your project README.
- Add a startup self-test in CI that validates your production DATABASE_URL against your pool config to catch conflicts before deploy.
- When setting useLibpqCompat programmatically, sanitize incoming connection strings by stripping uselibpqcompat.
When it happens
Trigger: Calling parse(connStr, { useLibpqCompat: true }) or new Pool({ connectionString, useLibpqCompat: true }) where connStr already contains '?...&uselibpqcompat=true'. Also triggered via ConnectionParameters when config.useLibpqCompat is set alongside a DATABASE_URL containing uselibpqcompat.
Common situations: A team standardizes SSL behavior by adding useLibpqCompat:true to pool config, but the DATABASE_URL env var (often set by a PaaS like Heroku/Render) already includes uselibpqcompat=true. Another case: copy-pasting a working psql/libpq connection string that had uselibpqcompat into code that also sets the programmatic option.
Related errors
- SECURITY WARNING: Using sslmode=verify-ca requires specifyin
- Invalid ${key}: ${value}
- Invalid sslnegotiation value: "${this.sslnegotiation}". Vali
- sslnegotiation=direct requires SSL to be enabled
- Client was passed a null or undefined query
AI-assisted analysis of brianc/node-postgres@c5e8c9a57b (2026-08-03).
Data as JSON: /data/errors/342c261bb0d91d1a.json.
Report an issue: GitHub.