You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Simplify update semantics to do whole object replace #1011
The way we do updates today is using AIP's field masks. Each Update<Resource>Request message has a google.protobuf.FieldMask update_mask field to specify the paths of fields to merge.
Considering that merge semantics have proven to be hard to get right (Kubernetes went through many iterations to get it right, with strategic merge patch, JSON patch, JSON merge patch, SSA) and that AIP-161 is vague on how to deal with things like non-scalar values (maps and repeated fields), I'm worried we won't get it right either, even more so if we rush it.
This task proposes we start with whole-object updates. This would remove the update_mask field completely and leave the resource field as the only field in the Update<Resource>Request message. Clients will be able to fence the update on either version or UID in the same way they do it today to prevent clients from overwriting each other (i.e. blind updates).
Note that this decision doesn't preclude us from adding some form of patch updates in the future. For example, we could add the update_mask field and let the default (no mask) be whole-object replacement. On the other hand, getting the merge semantics wrong would put us in a bad place where we have to support that forever.
Clients will be able to fence the update on either version or UID in the same way they do it today to prevent clients from overwriting each other (i.e. blind updates).
Clarify - are you proposing that clients MAY or MUST specify version and uid preconditions for updates?
On the other hand, getting the merge semantics wrong would put us in a bad place where we have to support that forever.
As the author of and repeated triager of several such bugs in k8s, I appreciate the sentiment :)
The combination of whole object update, with required preconditions for optimistic concurrency, and with preserved fields on the client side, is safe and defensible (and is skew safe!).
Considering that merge semantics have proven to be hard to get right (Kubernetes went through many iterations to get it right
This is too generous, actually. Only JSON patch is able to perform all possible patch operations, and it still requires the use of optimistic read/modify/write loops to manage conflicts safely.. SSA has capability gaps that we have not been able to fix. And there is client-side apply hidden there too, to the grand total is 5 patch mechanisms, none of which fully achieve both soundness and fire-and-forget.
Note that this decision doesn't preclude us from adding some form of patch updates in the future
For posterity, my current thinking on this is:
Even if you have a sound patch mechanism, the only way other to get conflict safety other than concurrently optimistic writes (read/modify/write with preconditions) is to pair a patch mechanism with field ownership tracking on the server.. In k8s this line of reasoning let to SSA. I think the complexity of this solution has proved to not be worth the cost.
If you accept that you're not investing on server side field ownership tracking. Then the choices are down to: (a) full object read/modify/write with preconditions, or (b) a patch operation using read/modify/write with preconditions. I don't see update_mask adding much value to the client for (b)...
Updates are already doing whole object replace + rejecting update requests containing unknown fields, so I'm closing this issue.
However, as discussed on the ate upgrade proposal and in #954, the server still needs to clear unknown fields on READ operations. But, we'll track that separately
Activity
thockin commentedon Aug 18, 2026
Clarify - are you proposing that clients MAY or MUST specify version and uid preconditions for updates?
As the author of and repeated triager of several such bugs in k8s, I appreciate the sentiment :)
I'm OK with this.
jpbetz commentedon Aug 18, 2026
I support this.
The combination of whole object update, with required preconditions for optimistic concurrency, and with preserved fields on the client side, is safe and defensible (and is skew safe!).
This is too generous, actually. Only JSON patch is able to perform all possible patch operations, and it still requires the use of optimistic read/modify/write loops to manage conflicts safely.. SSA has capability gaps that we have not been able to fix. And there is client-side apply hidden there too, to the grand total is 5 patch mechanisms, none of which fully achieve both soundness and fire-and-forget.
For posterity, my current thinking on this is:
update_maskadding much value to the client for (b)...juli4n commentedon Aug 18, 2026
I was considering making it a MUST.
laoj2 commentedon Aug 18, 2026
Also related to this: #954
Simplify Update methods to do a whole object replace (#1108)
Reject object updates containing unknown fields (#1174)
laoj2 commentedon Aug 25, 2026
Updates are already doing whole object replace + rejecting update requests containing unknown fields, so I'm closing this issue.
However, as discussed on the ate upgrade proposal and in #954, the server still needs to clear unknown fields on READ operations. But, we'll track that separately
cc Haven Xia (@HavenXia) to link the issue
HavenXia commentedon Aug 25, 2026
Thank you! tracked that in #1205
Create reject unknown fields (#1186)