Summary
PgDoorman rejects PostgreSQL StartupMessage packets containing an empty parameter value.
This affects clients using lib/pq. In particular, lib/pq v1.11.1 always includes the options parameter in the startup packet, even when its value is empty:
PgDoorman's parse_params() ignores every empty null-terminated string. As a result, it keeps the options key but drops its empty value, producing an odd number of parsed strings and rejecting the connection.
Error
Protocol synchronization error: Invalid client startup message: Expected key-value pairs, but received 7 parameters
Environment
- PgDoorman version:
3.10.7
- PostgreSQL driver:
github.com/lib/pq v1.11.1
- PostgreSQL SSL mode: disabled
Steps to reproduce
postgresql://my-user:my-password@pg-doorman-address:6432/my-database?sslmode=disable
PgDoorman rejects the startup packet with:
Invalid client startup message: Expected key-value pairs, but received 7 parameters
A representative startup parameter sequence is:
user\0my-user\0
database\0my-database\0
options\0\0
client_encoding\0UTF8\0
\0
Expected behavior
PgDoorman should accept empty parameter values.
In the PostgreSQL startup protocol:
- An empty parameter name marks the end of the parameter list.
- A parameter value may be empty.
options\0\0 should therefore be parsed as options = "", not as a missing value.
Actual behavior
In src/messages/protocol.rs, parse_params() only pushes a parsed string when it is non-empty:
if !tmp.is_empty() {
buf.push(tmp.clone());
tmp.clear();
}
This removes both:
- the final empty parameter-list terminator;
- legitimate empty parameter values.
After the empty options value is discarded, PgDoorman sees seven strings and reports an invalid key/value pair count.
Note
Upgrading clients to lib/pq v1.11.2 fixes the issue, as they stop sending empty options.
link to release
Workaround
Setting a non-empty options value allows the client to connect:
postgresql://my-user:my-password@pg-doorman-address:6432/my-database?sslmode=disable%20options='-c%20application_name=my-application'
This workaround has been tested successfully.
AI disclosure
This issue was drafted with assistance from ChatGPT. The reported behavior, reproduction steps, workaround, and technical details were manually verified before submission.
Summary
PgDoorman rejects PostgreSQL
StartupMessagepackets containing an empty parameter value.This affects clients using
lib/pq. In particular,lib/pq v1.11.1always includes theoptionsparameter in the startup packet, even when its value is empty:PgDoorman's
parse_params()ignores every empty null-terminated string. As a result, it keeps theoptionskey but drops its empty value, producing an odd number of parsed strings and rejecting the connection.Error
Environment
3.10.7github.com/lib/pq v1.11.1Steps to reproduce
postgresql://my-user:my-password@pg-doorman-address:6432/my-database?sslmode=disablePgDoorman rejects the startup packet with:
A representative startup parameter sequence is:
Expected behavior
PgDoorman should accept empty parameter values.
In the PostgreSQL startup protocol:
options\0\0should therefore be parsed asoptions = "", not as a missing value.Actual behavior
In
src/messages/protocol.rs,parse_params()only pushes a parsed string when it is non-empty:This removes both:
After the empty
optionsvalue is discarded, PgDoorman sees seven strings and reports an invalid key/value pair count.Note
Upgrading clients to
lib/pq v1.11.2fixes the issue, as they stop sending emptyoptions.link to release
Workaround
Setting a non-empty
optionsvalue allows the client to connect:postgresql://my-user:my-password@pg-doorman-address:6432/my-database?sslmode=disable%20options='-c%20application_name=my-application'This workaround has been tested successfully.
AI disclosure
This issue was drafted with assistance from ChatGPT. The reported behavior, reproduction steps, workaround, and technical details were manually verified before submission.