Change:
svctest.SetNodePorts(30118, 0)), // set [0] to HCNP's value, omit [1] expectError: true, }, <ins> }, { name: "update-hcnp", create: svcTestCase{ svc: svctest.MakeService("foo", svctest.SetTypeLoadBalancer, svctest.SetExternalTrafficPolicy(api.ServiceExternalTrafficPolicyTypeLocal), svctest.SetPorts( svctest.MakeServicePort("p", 867, intstr.FromInt(867), api.ProtocolTCP), svctest.MakeServicePort("q", 5309, intstr.FromInt(5309), api.ProtocolTCP)), svctest.SetNodePorts(30093, 30076), svctest.SetHealthCheckNodePort(30118)), expectClusterIPs:          true, expectNodePorts:           true, expectHealthCheckNodePort: true, }, update: svcTestCase{ svc: svctest.MakeService("foo", svctest.SetTypeLoadBalancer, svctest.SetExternalTrafficPolicy(api.ServiceExternalTrafficPolicyTypeLocal), svctest.SetPorts( svctest.MakeServicePort("p", 867, intstr.FromInt(867), api.ProtocolTCP), svctest.MakeServicePort("q", 5309, intstr.FromInt(5309), api.ProtocolTCP)), svctest.SetNodePorts(30093, 30076), svctest.SetHealthCheckNodePort(30111)), expectError: true, }, </ins> }} helpTestCreateUpdateDelete(t, testCases)

Discussion:
We are currently using v1.19 and it seems that if you have a service with set to then changing the health check node port is not supported. One way to get around this is by changing the to and then changing it back to in addition to specifying the with the desired port number. This behavior is not very well documented and the below error message is not very useful: I wonder if we could also add another case below to release the current health check port and allow changing it to the user specified value given it's valid? It's possible that after creating a someone wants to change it to a user-provided and the current way to do it is only by toggling the . This feature with the documentation would be more straightforward way to make any port changes.
This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the label and provide further guidance. The label can be by org members by writing in a comment. <detailsInstructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/sig network
19 is EOL, last supported version is 1.22 It seems the message has changed since then, this area had important changes in latest releases that improved the API behavior However, the field still can not be updated once set, what you do switching the is wiping the value and reallocating it. It is a documentation problem then
IMO, the amount of effort it would take to make this mutable is not justified when there is a workaround. Convince me the workaround doesn't work? Overall HCNP is a buried implementation detail.
I can't speak much to the amount of effort, but I can speak a bit to the value: a user, I don't expect healthcheckNodePort to be immutable. I'm not sure if my mental model is too simplistic, but it feels like a part of the configuration I control, and I can change NodePorts, so why not the healthcheckNodePort. the work around isn't necessarily obvious. It also takes experimenting with to know that it'll even work. this in a production environment is not trivial.

If changing the healthcheckNodePort was supported then you could change the config to the state you want it to be, and your rollout orchestration tooling goes and applies it to your collection of k8s clusters. With the work around you now have to have a 2 step process. After step 1 of this process your service is using a traffic policy which might break your application (say you depend on client ip). So to avoid the downtime you'd have to build some reasonably off-pattern orchestration that doesn't just apply the configuration from the commit you used for your release, but instead two commits, or two configs, etc. Operationally this isn't actually that cheap to build, especially as this is likely to be a one-off operation and not something you do every release. Not exactly the same thing, but related to healthcheckNodePort, I've also found that specifying it explicitly vs not explicitly in the config, and switching between the two modes, has unexpected behavior as well. If you started out as having it specified, applying a config with it unspecified tries to allocate a new value, and complains that it can't change healthcheckNodePort for traffic policy local. Why not just use the already allocated value? Going from unallocated to specifying it explicitly at the same value seems to works fine.
The latter issue should be fixed in recent releases - what version are you seeing that on? I understand it would be more consistent to be mutable but there are real downstream implications to changing it, code complexity, test complexity, etc, and I don't understand why you want to change it in the first place. Humans should not be paying attention to that field. It should not even be in spec, but for historical reasons.
Same version as original post, v1.19. Glad to hear that issue is fixed in later versions! We're making steady progress updating, but not all caught up yet. I don't want to insist on this fix, as I said I'm not aware of the fix complexity and leave it up to you guys to balance that out, just wanted to provide the value perspective. As for not being exposed to users at all, I think we'd probably have been better off if we never knew about it.

Unfortunately our original configs had it explicitly set, eventually ran into conflicts in various k8s clusters and tried to transition to having it be unspecified, and thus ran into the above situation.
Yeah, there's really no good reason to set it, pretty much ever, and lots of reasons not to. I will cross-check that it is fixed if I get a moment tomorrow.
It has been fixed by you Tim
I thought so, I just wanted to triple check :)