kubernetes/kops · error

parsing additional containerd config entry %q: %w

Error message

parsing additional containerd config entry %q: %w

What it means

applyConfigAdditions (nodeup/pkg/model/containerd.go:580) parses each user-provided ConfigAdditions key as a CSV record with '.' as the delimiter, so dotted plugin names can be quoted. This error is raised when csv.Reader.Read() fails on a key — typically malformed quoting (unclosed or stray double-quote characters) in the key string. The %q shows the exact offending entry.

Source

Thrown at nodeup/pkg/model/containerd.go:580

// Each key is parsed as a CSV record using '.' as the separator, so quoted dots inside
// plugin names like `plugins."io.containerd.grpc.v1.cri".sandbox_image` survive the split.
// Paths are written verbatim; the user is responsible for matching the schema version of
// the configured containerd binary (v3 vs v4).
// Keys are applied in sorted order so output is reproducible across runs.
func applyConfigAdditions(config *tomlwriter.Tree, additions map[string]intstr.IntOrString) error {
	keys := make([]string, 0, len(additions))
	for k := range additions {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, k := range keys {
		v := additions[k]
		r := csv.NewReader(strings.NewReader(k))
		r.Comma = '.'
		path, err := r.Read()
		if err != nil {
			return fmt.Errorf("parsing additional containerd config entry %q: %w", k, err)
		}

		if v.Type == intstr.Int {
			config.SetPath(path, int64(v.IntValue()))
			continue
		}
		switch s := v.String(); s {
		case "true":
			config.SetPath(path, true)
		case "false":
			config.SetPath(path, false)
		default:
			config.SetPath(path, s)
		}
	}
	return nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Look at the %q key in the error and find the quote mistake
  2. Wrap every dotted plugin name in its own double quotes: plugins."io.containerd.cri.v1.runtime".enable_selinux
  3. Ensure quotes are balanced — no stray leading/trailing quote on the whole key
  4. Test the key locally: strings.Split equivalent via encoding/csv with Comma='.' should yield the expected path segments

Example fix

// before
"plugins."io.containerd.cri.v1.runtime".enable_selinux: true"  // stray outer quotes
// after
plugins."io.containerd.cri.v1.runtime".enable_selinux: true
Defensive patterns

Strategy: validation

Validate before calling

func validConfigAdditionsKey(k string) error {
    r := csv.NewReader(strings.NewReader(k))
    r.Comma = '.'
    _, err := r.Read()
    return err
}
// run over every spec.containerd.configAdditions key before kops update

Try / catch

path, err := r.Read()
if err != nil {
    return fmt.Errorf("parsing additional containerd config entry %q: %w", k, err)
}
// inspect %q and errors.Is(err, csv.ErrBareQuote|csv.ErrQuote) to pinpoint the quoting flaw

Prevention

When it happens

Trigger: A ConfigAdditions map key contains a bare or unbalanced '"' character, e.g. plugins."io.containerd.grpc.v1.cri.sandbox_image (missing closing quote) — the CSV reader returns ErrBareQuote / ErrQuote and the key cannot be split into a TOML path.

Common situations: Users edit spec.containerd.configAdditions in the cluster manifest by hand and mistype the quote placement around dotted containerd plugin names; older examples copied from containerd v1 docs use the old grpc plugin path with wrong quoting.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/dbb1cb4a77294554. Report an issue: GitHub.