{"record":{"id":"1372a3333a6915fc","repo":"kubernetes/kops","slug":"applying-configadditions-to-containerd-config-w","errorCode":null,"errorMessage":"applying ConfigAdditions to containerd config: %w","messagePattern":"applying ConfigAdditions to containerd config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nodeup/pkg/model/containerd.go","lineNumber":526,"sourceCode":"\tconfig.SetPath([]string{\"plugins\", \"io.containerd.cri.v1.runtime\", \"containerd\", \"runtimes\", \"runc\", \"runtime_type\"}, \"io.containerd.runc.v2\")\n\tconfig.SetPath([]string{\"plugins\", \"io.containerd.cri.v1.runtime\", \"containerd\", \"runtimes\", \"runc\", \"options\", \"SystemdCgroup\"}, true)\n\tif b.NodeupConfig.UsesKubenet {\n\t\t// Using containerd with Kubenet requires special configuration.\n\t\t// This is a temporary backwards-compatible solution for kubenet users and will be deprecated when Kubenet is deprecated:\n\t\t// https://github.com/containerd/containerd/blob/master/docs/cri/config.md#cni-config-template\n\t\tconfig.SetPath([]string{\"plugins\", \"io.containerd.cri.v1.runtime\", \"cni\", \"conf_template\"}, \"/etc/containerd/config-cni.template\")\n\t}\n\n\tif b.InstallNvidiaRuntime() {\n\t\tappendNvidiaGPURuntimeConfig(config.Table(\"plugins\", \"io.containerd.cri.v1.runtime\", \"containerd\", \"runtimes\"))\n\t}\n\n\tif b.InstallGVisorRuntime() {\n\t\tappendGVisorRuntimeConfig(config.Table(\"plugins\", \"io.containerd.cri.v1.runtime\", \"containerd\", \"runtimes\"))\n\t}\n\n\tif err := applyConfigAdditions(config, containerd.ConfigAdditions); err != nil {\n\t\treturn \"\", fmt.Errorf(\"applying ConfigAdditions to containerd config: %w\", err)\n\t}\n\n\treturn config.String(), nil\n}\n\n// usesOSContainerd reports whether kops only configures a distro-supplied containerd,\n// whose version spec.containerd.version does not identify.\nfunc (b *ContainerdBuilder) usesOSContainerd() bool {\n\tswitch b.Distribution {\n\tcase distributions.DistributionFlatcar, distributions.DistributionContainerOS:\n\t\treturn true\n\t}\n\treturn false\n}\n\n// containerdConfigVersion returns the config version to declare in the generated config.toml:\n// 4 for containerd >= 2.3, otherwise 3.\n// Both bounds matter: containerd 2.1 and 2.2 reject version 4, while 2.3.0-2.3.4 refuse","sourceCodeStart":508,"sourceCodeEnd":544,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/nodeup/pkg/model/containerd.go#L508-L544","documentation":"buildContainerdConfig (nodeup/pkg/model/containerd.go:526) assembles the generated containerd config.toml (v3/v4 schema) and then applies user-supplied ConfigAdditions via applyConfigAdditions. If any ConfigAdditions entry cannot be parsed or applied, the failure is wrapped with this message. It means one of the cluster spec's spec.containerd.configAdditions entries is malformed (bad key path or unusable value), not a containerd runtime problem.","triggerScenarios":"Any containerd >= 2.0 node build where containerd.ConfigAdditions is non-empty and applyConfigAdditions fails — specifically when a ConfigAdditions key cannot be parsed as a dot-separated path by the CSV reader (e.g. unbalanced quotes or bare-broken CSV syntax in the key).","commonSituations":"Users hand-write configAdditions in the cluster spec and quote plugin names incorrectly, e.g. plugins.\"io.containerd...\".sandbox_image with mismatched quotes, or copy keys from a v1-style config that don't fit the current schema. Build fails in nodeup before containerd ever starts.","solutions":["Read the wrapped inner error to identify the offending key","Fix the quoting of the offending configAdditions key in the cluster spec; plugin names with dots must be wrapped in escaped quotes, e.g. plugins.\"io.containerd.cri.v1.runtime\".sandbox_image","Validate the full entry parses as a CSV record with Comma='.' before deploying","Remove the bad entry temporarily to let the node build, then re-add a corrected version"],"exampleFix":"// before (cluster spec)\nconfigAdditions:\n  plugins.\"io.containerd.cri.v1.runtime.sandbox_image: registry.k8s.io/pause:3.10\n// after\nconfigAdditions:\n  plugins.\"io.containerd.cri.v1.runtime\".sandbox_image: registry.k8s.io/pause:3.10","handlingStrategy":"validation","validationCode":"// Validate each configAdditions key parses before applying it to the cluster:\nfor k := range cfg.ContainerdConfig.ConfigAdditions {\n    r := csv.NewReader(strings.NewReader(k))\n    r.Comma = '.'\n    if _, err := r.Read(); err != nil {\n        return fmt.Errorf(\"invalid configAdditions key %q: %w\", k, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := applyConfigAdditions(config, additions); err != nil {\n    return \"\", fmt.Errorf(\"applying ConfigAdditions to containerd config: %w\", err)\n}\n// caller: errors.Unwrap(err) reveals the exact key that failed","preventionTips":["Quote dotted plugin names exactly as containerd docs show: plugins.\"io.containerd.cri.v1.runtime\".field","Validate the cluster spec with kops before rolling nodes (kops update cluster --dry-run)","Test config changes on a single node / dev cluster first","Match keys to the containerd config schema version (v3 vs v4) your containerd binary uses"],"tags":["containerd","config","toml","configuration"],"backgroundTag":"invalid-config-additions","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}