brianc/node-postgres · error · Error
Invalid sslnegotiation value: "${this.sslnegotiation}". Vali
Error message
Invalid sslnegotiation value: "${this.sslnegotiation}". Valid values are "postgres" and "direct". What it means
Thrown by the ConnectionParameters constructor (connection-parameters.js:105-108) when the sslnegotiation setting is set to a value other than 'postgres' or 'direct' (or undefined). sslnegotiation controls how the client initiates TLS: 'postgres' (default) uses the traditional SSLRequest packet, 'direct' begins the TLS handshake immediately. An unrecognized value indicates a typo or a setting from a different client library. The value can come from config.sslnegotiation or the PGSSLNEGOTIATION environment variable.
Source
Thrown at packages/pg/lib/connection-parameters.js:106
if (this.ssl === 'true') {
this.ssl = true
}
}
// support passing in ssl=no-verify via connection string
if (this.ssl === 'no-verify') {
this.ssl = { rejectUnauthorized: false }
}
if (this.ssl && this.ssl.key) {
Object.defineProperty(this.ssl, 'key', {
enumerable: false,
})
}
// How to negotiate SSL: 'postgres' (default, the traditional SSLRequest
// handshake) or 'direct' (start the TLS handshake immediately on connect).
this.sslnegotiation = val('sslnegotiation', config, 'PGSSLNEGOTIATION')
if (this.sslnegotiation !== undefined && this.sslnegotiation !== 'postgres' && this.sslnegotiation !== 'direct') {
throw new Error(
`Invalid sslnegotiation value: "${this.sslnegotiation}". Valid values are "postgres" and "direct".`
)
}
if (this.sslnegotiation === 'direct' && !this.ssl) {
throw new Error('sslnegotiation=direct requires SSL to be enabled')
}
this.client_encoding = val('client_encoding', config)
this.replication = val('replication', config)
// a domain socket begins with '/'
this.isDomainSocket = !(this.host || '').indexOf('/')
this.application_name = val('application_name', config, 'PGAPPNAME')
this.fallback_application_name = val('fallback_application_name', config, false)
this.statement_timeout = val('statement_timeout', config, false)
this.lock_timeout = val('lock_timeout', config, false)
this.idle_in_transaction_session_timeout = val('idle_in_transaction_session_timeout', config, false)
this.query_timeout = val('query_timeout', config, false)View on GitHub (pinned to c5e8c9a57b)
Solutions
- Set sslnegotiation to 'postgres' (default, SSLRequest handshake) or 'direct' (immediate TLS).
- If you do not need direct TLS negotiation, remove the sslnegotiation setting entirely to use the default.
- Check the PGSSLNEGOTIATION environment variable in your deployment environment and correct or unset it.
Example fix
// before
const client = new Client({ ssl: true, sslnegotiation: 'prefer' });
// after
const client = new Client({ ssl: true, sslnegotiation: 'direct' });
// or omit it for the default
const client = new Client({ ssl: true }); Defensive patterns
Strategy: validation
Validate before calling
const VALID_SSL_NEGOTIATION = ['postgres', 'direct', undefined];
function validateSslNegotiation(config) {
const val = config.sslnegotiation ?? process.env.PGSSLNEGOTIATION;
if (!VALID_SSL_NEGOTIATION.includes(val)) {
throw new Error(
`sslnegotiation '${val}' is invalid. Use 'postgres' or 'direct', or omit it.`
);
}
} Type guard
function isSslNegotiation(v) {
return v === undefined || v === 'postgres' || v === 'direct';
} Prevention
- Do not confuse sslmode values (prefer/require/verify-full) with sslnegotiation values (postgres/direct).
- Check the PGSSLNEGOTIATION environment variable in your deployment before connecting.
- If you do not need direct TLS, omit sslnegotiation entirely to use the safe default.
When it happens
Trigger: Passing { sslnegotiation: 'prefer' } or setting PGSSLNEGOTIATION=auto. Any value that is not undefined, 'postgres', or 'direct' triggers the throw at line 106.
Common situations: Confusing sslmode values (prefer/require/verify-full) with sslnegotiation values. Setting PGSSLNEGOTIATION to an invalid string in a deployment manifest. Copying a configuration from a different PostgreSQL driver that supports different negotiation modes.
Related errors
- Both useLibpqCompat and uselibpqcompat are set. Please use o
- sslnegotiation=direct requires SSL to be enabled
- SECURITY WARNING: Using sslmode=verify-ca requires specifyin
- Invalid ${key}: ${value}
- Client was passed a null or undefined query
AI-assisted analysis of brianc/node-postgres@c5e8c9a57b (2026-08-03).
Data as JSON: /data/errors/606d6a69b912f053.json.
Report an issue: GitHub.