BUG #19795: pgoutput: walsender crashes on START_REPLICATION option without a value

From: PG Bug reporting form <noreply(at)postgresql(dot)org>
To: pgsql-bugs(at)lists(dot)postgresql(dot)org
Cc: brar(at)gmx(dot)de
Subject: BUG #19795: pgoutput: walsender crashes on START_REPLICATION option without a value
Date: 2026-10-24 22:28:23
Message-ID: 19795-6d7d506133b7f062@postgresql.org
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

The following bug has been logged on the website:

Bug reference: 19795
Logged by: Brar Piening
Email address: brar(at)gmx(dot)de
PostgreSQL version: 18.6
Operating system: Windows 11 x64 (EDB installer builds)
Description:

A START_REPLICATION option without a value crashes the walsender when the
output plugin is pgoutput and the option is proto_version or
publication_names.
The postmaster then restarts all sessions.
A role with REPLICATION is enough; it doesn't need to be a superuser.

Steps, on a fresh cluster with wal_level = logical:

-- as a superuser
CREATE PUBLICATION pub FOR ALL TABLES;
SELECT pg_create_logical_replication_slot('s', 'pgoutput');
CREATE ROLE repuser LOGIN REPLICATION;

pg_recvlogical -d postgres -U repuser --slot=s --start -o proto_version \
-f - --no-loop

(Without --no-loop, pg_recvlogical sends the command again after a few
seconds.)

pg_recvlogical sends START_REPLICATION SLOT "s" LOGICAL 0/0
("proto_version")
and reports:

pg_recvlogical: error: could not send replication command
"START_REPLICATION SLOT "s" LOGICAL 0/0 ("proto_version")": server closed
the connection unexpectedly

Server log (18.6):

LOG: client backend (PID 21132) was terminated by exception 0xC0000005
DETAIL: Failed process was running: START_REPLICATION SLOT "s" LOGICAL
0/0 ("proto_version")
LOG: terminating any other active server processes
LOG: all server processes terminated; reinitializing
LOG: database system was not properly shut down; automatic recovery in
progress
...
LOG: database system is ready to accept connections

"-o publication_names" crashes the same way. I reproduced both on 14.24,
15.19, 16.15, 17.11 and 18.6, all Windows builds, where the crash shows up
as an access violation.

Expected: an error, as for pgoutput's origin option without a value:

ERROR: origin requires a parameter
CONTEXT: slot "s", output plugin "pgoutput", in the startup callback

Cause: the replication grammar accepts an option without a value and leaves
DefElem.arg NULL (repl_gram.y, plugin_opt_arg: "| /* EMPTY */ { $$ = NULL;
}").
parse_output_parameters() in pgoutput.c allows this ("Assert(defel->arg ==
NULL || IsA(defel->arg, String))"), but for proto_version and
publication_names it calls strVal(defel->arg), which dereferences the NULL
pointer.
The other options are read with defGetBoolean() (a missing value means true)
or defGetString() (origin, which raises the error above).
The SQL functions such as pg_logical_slot_get_changes() can't produce a NULL
arg, since logicalfuncs.c wraps every value in makeString().
So only the replication protocol path crashes.
test_decoding checks for a NULL arg itself.

Suggested fix: read both options with defGetString(defel), as origin does,
on all supported branches.

I found this while working on Npgsql (the .NET driver), whose generic
logical replication API currently sends an option without a value when the
caller passes null.

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Andrey Borodin 2026-10-25 00:38:09 Re: BUG #19794: Assert in btvacuumcleanup() fails when page counted in pages_free twice
Previous Message Tom Lane 2026-10-24 18:27:52 Re: GIN jsonb_ops misses root strings in strict jsonpath queries