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
- Start from a pre-KV config with
notify_postgres (or notify_mysql) enabled, in either the connection-string or the discrete-field form.
- Start a server that performs the config migration.
- 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.
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.
SetNotifyPostgresandSetNotifyMySQL(internal/config/notify/legacy.go), the migration helpers called fromcmd/config-migrate.go, write five keys —host,port,username,password,database— that neitherDefaultPostgresKVSnorDefaultMySQLKVSregistered, and thatGetNotifyPostgres/GetNotifyMySQLnever read.Config.CheckValidKeysmatches 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.
FetchEnabledTargetsreturns 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,
passwordhere is a plaintext database password. Because the key was unregistered it carried noSensitiveflag, so it was written verbatim into health and diagnostic bundles rather than redacted.Steps to Reproduce
notify_postgres(ornotify_mysql) enabled, in either the connection-string or the discrete-field form.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 bothNewPostgreSQLTargetandNewMySQLTargetassembling 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, andpasswordnow carries aSensitiveflag 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 isuser=, which a server rejects as an unrecognized configuration parameter. The MySQL side has no equivalent problem — it builds its DSN throughmysql.Config.FormatDSN.The source-level audit added for #39 now has an empty
knownUnregisteredWrites; these ten entries were the last of it.