{"record":{"id":"4910fc906ffa10a8","repo":"k3s-io/k3s","slug":"toleration-with-operator-exists-must-have-an-emp","errorCode":null,"errorMessage":"toleration with operator 'Exists' must have an empty value","messagePattern":"toleration with operator 'Exists' must have an empty value","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cloudprovider/servicelb.go","lineNumber":738,"sourceCode":"\t\t\treturn nil, fmt.Errorf(\"validation failed for toleration %d: %v\", i, err)\n\t\t}\n\t}\n\n\treturn tolerations, nil\n}\n\n// validateToleration ensures a toleration has valid fields according to its operator.\nfunc validateToleration(toleration *core.Toleration) error {\n\tif toleration.Operator == \"\" {\n\t\ttoleration.Operator = core.TolerationOpEqual\n\t}\n\n\tif toleration.Key == \"\" && toleration.Operator != core.TolerationOpExists {\n\t\treturn errors.New(\"toleration with empty key must have operator 'Exists'\")\n\t}\n\n\tif toleration.Operator == core.TolerationOpExists && toleration.Value != \"\" {\n\t\treturn errors.New(\"toleration with operator 'Exists' must have an empty value\")\n\t}\n\n\treturn nil\n}\n\n// generateName generates a distinct name for the DaemonSet based on the service name and UID\nfunc generateName(svc *core.Service) string {\n\tname := svc.Name\n\t// ensure that the service name plus prefix and uuid aren't overly long, but\n\t// don't cut the service name at a trailing hyphen.\n\tif len(name) > 48 {\n\t\ttrimlen := 48\n\t\tfor name[trimlen-1] == '-' {\n\t\t\ttrimlen--\n\t\t}\n\t\tname = name[0:trimlen]\n\t}\n\treturn fmt.Sprintf(\"svclb-%s-%s\", name, svc.UID[:8])","sourceCodeStart":720,"sourceCodeEnd":756,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/cloudprovider/servicelb.go#L720-L756","documentation":"In Kubernetes semantics, operator 'Exists' matches any value for the given key, so carrying a Value on the same toleration is contradictory. validateToleration enforces this for tolerations parsed from the ServiceLB annotation and rejects the pair.","triggerScenarios":"Service annotated with `servicelb.k3s.io/tolerations: '[{\"key\":\"foo\",\"operator\":\"Exists\",\"value\":\"bar\"}]'` — any combination where operator is Exists and value is a non-empty string.","commonSituations":"Converting an Equal toleration to Exists and forgetting to delete the value field; templating engines that always emit a value field; copy-paste between annotations and pod specs that skips cleanup.","solutions":["Remove the value field when using operator Exists","If the value matters, use the default operator Equal with key and value set","Lint the annotation JSON before applying (operator Exists ⇒ value must be absent/empty)"],"exampleFix":"# before\n[{\"key\":\"special\",\"operator\":\"Exists\",\"value\":\"true\"}]\n\n# after\n[{\"key\":\"special\",\"operator\":\"Exists\"}]","handlingStrategy":"validation","validationCode":"// reject Exists-with-value before annotating\nfor _, t := range parsedTolerations {\n    if t.Operator == core.TolerationOpExists && t.Value != \"\" {\n        return fmt.Errorf(\"toleration key=%q: operator Exists must not set value\", t.Key)\n    }\n}","typeGuard":"func existsTolerationHasNoValue(t core.Toleration) bool {\n    return t.Operator != core.TolerationOpExists || t.Value == \"\"\n}","tryCatchPattern":null,"preventionTips":["Strip value fields when converting Equal tolerations to Exists","Mirror k8s API validation semantics in any tooling that writes tolerations","Lint ServiceLB annotations in CI with a JSON schema including operator/value exclusivity"],"tags":["servicelb","tolerations","kubernetes","validation"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}