Skip to content

Migrating a Postgres or MySQL notify config disables all bucket notifications #53

Description

@Vonng

Expected Behavior

Migrating a pre-KV configuration that has a Postgres or MySQL notification target should produce a configuration that loads.

Current Behavior

It produces one that is rejected, and the rejection takes every other notification target down with it.

SetNotifyPostgres and SetNotifyMySQL (internal/config/notify/legacy.go), the migration helpers called from cmd/config-migrate.go, write five keys — host, port, username, password, database — that neither DefaultPostgresKVS nor DefaultMySQLKVS registered, and that GetNotifyPostgres / GetNotifyMySQL never read.

Config.CheckValidKeys matches on key name and ignores the value, so this is not limited to configurations that used the discrete-field form. A target migrated from the connection-string form carries the same five keys written empty, and is rejected identically.

The blast radius is the part worth emphasising. FetchEnabledTargets returns on the first failing sub-system, so a single migrated Postgres target disables all bucket notifications — webhook, Kafka, NATS, everything — with a single log line naming only the Postgres sub-system.

Separately, password here is a plaintext database password. Because the key was unregistered it carried no Sensitive flag, so it was written verbatim into health and diagnostic bundles rather than redacted.

Steps to Reproduce

  1. Start from a pre-KV config with notify_postgres (or notify_mysql) enabled, in either the connection-string or the discrete-field form.
  2. Start a server that performs the config migration.
  3. Restart. Bucket notifications are gone; the log names only the Postgres or MySQL sub-system.

Resolution

Fixed in 6cb6fa90c, shipping in the next release.

Three of the four links this needed were already present: the struct fields, Validate() accepting the discrete form as an alternative to the connection string, and both NewPostgreSQLTarget and NewMySQLTarget assembling a connection string from those fields when the string one is empty. Even the environment-variable names were declared. Only the registration and the read were missing, so the fix completes that wiring rather than adding a configuration form — nothing that worked before changes, and password now carries a Sensitive flag and is redacted.

One defect was uncovered on the newly reachable path and fixed with it: the Postgres assembly emitted username=, while libpq's keyword is user=, which a server rejects as an unrecognized configuration parameter. The MySQL side has no equivalent problem — it builds its DSN through mysql.Config.FormatDSN.

The source-level audit added for #39 now has an empty knownUnregisteredWrites; these ten entries were the last of it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions