Skip to content

PgDoorman rejects PostgreSQL StartupMessage packets containing an empty parameter value. #274

Description

@sampletext32

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:

options\0\0

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions