Skip to content

Setting properties explicitly to null does not work without specifying --server-side #129456

Closed as not planned
@dervoeti

Description

What happened?

When running kubectl apply without --server-side, it is not possible to explicitly set a resource property to null.

Until Kubernetes 1.31 this was possible when a resource was created (not when it was patched), I think this behavior was removed by #125646.

My use case:
I have a CRD that specifies a default value for a property but allows it to be null: a value for default is specified and nullable is set to true in the CRD definition. So a user can either omit the property (default value should be used) or explicitly set it to null (then it should be null).
When I create a resource of that kind by running kubectl apply without --server-side, it is not possible to set the value to null, the property will always be set to the default value (which does not match the behavior described in the documentation).

Both for creating and patching, we need to think about whether the property should have the same value after running kubectl apply, no matter if --server-side is provided or not (currently the value depends on the flag being present).

What did you expect to happen?

The property's value should be null if the user explcitly sets it to null and the CRD allows it.

How can we reproduce it (as minimally and precisely as possible)?

Create the CRD:

cat <<EOF | kubectl apply -f -
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: fooclusters.example.tech
spec:
  group: example.tech
  names:
    kind: FooCluster
    listKind: FooClusterList
    plural: fooclusters
    shortNames:
    - foo
    singular: foocluster
  scope: Namespaced
  versions:
  - name: v1alpha1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        required:
        - spec
        type: object
        properties:
          spec:
            type: object
            properties:
              bar:
                type: string
                nullable: true
                default: "defaultvalue"
EOF

Create the resource:

cat <<EOF | kubectl apply -f -
apiVersion: example.tech/v1alpha1
kind: FooCluster
metadata:
  name: myfoocluster
spec:
  bar: null
EOF

Try running this with and without --server-side and check the property's value with:

kubectl get fooclusters.example.tech myfoocluster -o jsonpath='{.spec.bar}'

Anything else we need to know?

No response

Kubernetes version

$ kubectl version
Client Version: v1.31.2
Kustomize Version: v5.4.2
Server Version: v1.31.0

Cloud provider

Local Kind cluster

OS version

# On Linux:
$ cat /etc/os-release
# paste output here
$ uname -a
# paste output here

# On Windows:
C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture
# paste output here

Install tools

Container runtime (CRI) and version (if applicable)

Related plugins (CNI, CSI, ...) and versions (if applicable)

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.needs-triageIndicates an issue or PR lacks a `triage/foo` label and requires one.sig/api-machineryCategorizes an issue or PR as relevant to SIG API Machinery.sig/cliCategorizes an issue or PR as relevant to SIG CLI.

    Type

    No type

    Projects

    • Status

      Closed

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions