PostgreSQL logical replication and v2025.1 upgrade

03 October 2025
Product Affected Versions Related Issues Fixed In
CDC v2025.1.0 #27177 v2025.1.1

Description

When you upgrade a YugabyteDB universe from a version running PostgreSQL 11 (all versions prior to v2.25) to a version based on PostgreSQL 15 (v2025.1 or later (stable) or v2.25 or later (preview)), the PostgreSQL catalog tables are deleted and recreated as part of the upgrade process.

If a logical replication stream was active on the universe before the upgrade and was lagging at the time of the upgrade, the stream will begin erroring out after the upgrade. This is because logical replication (the walsender process) relies on querying the PostgreSQL catalog tables as of a past time to accurately determine the polling table list and their schemas when the stream is lagging. After the upgrade, the walsender will encounter an error if it attempts to query data from catalog tables pertaining to a time before the upgrade, rendering the replication slot useless.

This issue only affects the logical replication model of Change Data Capture (CDC) using logical replication. If you use CDC with gRPC replication, you can upgrade to PostgreSQL 15 versions of YugabyteDB without any issues.

Mitigation

There is no workaround to recover a stream that encounters this error with the walsender process on YugabyteDB v2025.1.0. To proceed and resume replication, you must drop the existing replication slot and create a new one.

If you rely on logical replication and plan to upgrade to YugabyteDB v2025.1.0 or later, note that you will need to create a new replication slot after the upgrade.

If you use logical replication and are planning to upgrade to YugabyteDB v2025.1.1 or later, refer to YSQL major upgrade.

Details

When this issue occurs, the walsender process will crash and throw the following error:

ERROR:  catalog version for database 16640 was not found.
HINT:  Database might have been dropped by another user
STATEMENT:  START_REPLICATION SLOT "test_slot" LOGICAL 0/2D3B0 ("proto_version" '1', "publication_names" 'test_pub', "messages" 'true')

This error is propagated to the client and is seen as the following exception:

2025-08-28 10:44:59,574 WARN   ||  WorkerSourceTask{id=ybconnector_cdc_6715a3_test_cdc_d90c28_hash-0} failed to poll records from SourceTask. Will retry operation.   [org.apache.kafka.connect.runtime.AbstractWorker
org.apache.kafka.connect.errors.RetriableException: An exception occurred in the change event producer. This connector will be restarted.
        at io.debezium.pipeline.ErrorHandler.setProducerThrowable(ErrorHandler.java:63)
        at io.debezium.connector.postgresql.PostgresStreamingChangeEventSource.execute(PostgresStreamingChangeEventSource.java:248)
        at io.debezium.connector.postgresql.PostgresStreamingChangeEventSource.execute(PostgresStreamingChangeEventSource.java:44)
        at io.debezium.pipeline.ChangeEventSourceCoordinator.streamEvents(ChangeEventSourceCoordinator.java:271)
        at io.debezium.connector.postgresql.PostgresChangeEventSourceCoordinator.executeChangeEventSources(PostgresChangeEventSourceCoordinator.java:100)
        at io.debezium.pipeline.ChangeEventSourceCoordinator.lambda$start$0(ChangeEventSourceCoordinator.java:137)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.yugabyte.util.PSQLException: ERROR: catalog version for database 16640 was not found.
  Hint: Database might have been dropped by another user
        at com.yugabyte.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2675)
        at com.yugabyte.core.v3.QueryExecutorImpl.processCopyResults(QueryExecutorImpl.java:1263)
        at com.yugabyte.core.v3.QueryExecutorImpl.readFromCopy(QueryExecutorImpl.java:1163)
        at com.yugabyte.core.v3.CopyDualImpl.readFromCopy(CopyDualImpl.java:44)
        at com.yugabyte.core.v3.replication.V3PGReplicationStream.receiveNextData(V3PGReplicationStream.java:160)
        at com.yugabyte.core.v3.replication.V3PGReplicationStream.readInternal(V3PGReplicationStream.java:125)
        at com.yugabyte.core.v3.replication.V3PGReplicationStream.readPending(V3PGReplicationStream.java:82)
        at io.debezium.connector.postgresql.connection.PostgresReplicationConnection$1.readPending(PostgresReplicationConnection.java:669)
        at io.debezium.connector.postgresql.PostgresStreamingChangeEventSource.processMessages(PostgresStreamingChangeEventSource.java:283)
        at io.debezium.connector.postgresql.PostgresStreamingChangeEventSource.execute(PostgresStreamingChangeEventSource.java:245)
        ... 9 more