Strategic Merge appends list elements instead of replacing them (JSON Patch unsupported for multi-document config)
Bug Report
Description
Hi everyone! 👋
We’ve encountered the following issue — our JSON patches stopped applying after adding an additional resource UserVolumeConfig to the main machine configuration.
Obviously, this happens because “JSON patches don’t support multi-document machine configuration, while strategic merge patches do.”
As we understand it, Talos is evolving toward splitting the monolithic machine configuration into multiple resource types:
UserVolumeConfig, EthernetConfig, HostnameConfig, ResolverConfig, TimeSyncConfig, etc.
This is also mentioned in issue #10925, meaning that Talos configuration is moving toward being multi-document, but nowhere is it stated that support for JSON patches (RFC 6902) is deprecated or planned for removal in future releases.
We had no choice but to switch from JSON patches to Strategic Merge Patches for applying our configurations — however, there’s an important nuance here.
When applying a patch to an existing configuration, list-type elements are appended instead of being replaced, which makes it impossible to apply the same patch repeatedly (idempotently) without modifications.
See:
This behavior breaks the GitOps workflow, since it prevents reapplying the same configuration manifest to achieve a consistent state. With JSON patches, this was never an issue — everything worked fine.
Why isn’t it possible to use the replace behavior by default for list elements when applying a strategic merge patch?
Or as an alternative
Strategic Merge Patch already supports the $patch: delete directive, but it does not support $patch: replace.
Adding support for $patch: replace would be an ideal compromise if there are strong reasons not to make “replace” the default behavior for list elements.
Update:
Additionally, I’d like to propose adding an extra argument to the talosctl mc patch command, for example:
--strategy-merge-patch append # default behavior
--strategy-merge-patch replace
—or, perhaps a better naming option—
--merge-strategy-behavior append # default
--merge-strategy-behavior replace
This would provide additional flexibility when choosing the desired behavior for applying patches and would also make it unnecessary to use the $patch: replace directive directly within the patch manifest, if it’s not required.
Logs
Environment
- Talos version: 1.11.2
- Kubernetes version: 1.32.9
- Platform: Proxmox