cilium/cilium · error

could not write %q: %w

Error message

could not write %q: %w

What it means

When the kvstore list command is given a second positional argument, it writes the collected key/value output to that local file path (resolved relative to the script state) instead of stdout. This error wraps any os.WriteFile failure — permissions, bad path, directory missing — with the offending path quoted.

Source

Thrown at pkg/kvstore/commands.go:139

						outfmt, _ := s.Flags.GetString("output")
						switch outfmt {
						case "plain":
							fmt.Fprintln(&b, string(v))
						case "json":
							if err := json.Indent(&b, v, "", "  "); err != nil {
								fmt.Fprintf(&b, "ERROR: %s", err)
							}
							fmt.Fprintln(&b)
						default:
							return "", "", fmt.Errorf("unexpected output format %q", outfmt)
						}
					}
				}
				if len(args) == 2 {
					err = os.WriteFile(s.Path(args[1]), b.Bytes(), 0644)
					if err != nil {
						err = fmt.Errorf("could not write %q: %w", s.Path(args[1]), err)
					}
				} else {
					stdout = b.String()
				}
				return
			}, nil
		},
	)
}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Verify the target directory exists and is writable (mkdir -p, chmod/chown)
  2. Write to a path the process can access, e.g. under /tmp
  3. Check disk space and whether the filesystem is mounted read-only
  4. Ensure the second argument is a file path, not a directory

Example fix

// before
kvstore list prefix /etc/cilium/backup.json
// after
mkdir -p /etc/cilium && kvstore list prefix /etc/cilium/backup.json
Defensive patterns

Strategy: validation

Validate before calling

dest := args[1]
if st, err := os.Stat(filepath.Dir(dest)); err != nil || !st.IsDir() {
    return fmt.Errorf("directory for %q is not writable", dest)
}
f, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
    return fmt.Errorf("cannot write %q: %w", dest, err)
}
f.Close()

Type guard

func writableFile(path string) bool {
    if st, err := os.Stat(path); err == nil && st.IsDir() {
        return false
    }
    f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644)
    if err != nil {
        return false
    }
    f.Close()
    return true
}

Try / catch

stdout, stderr, err := runKvstoreList(ctx, prefix, dest)
if err != nil && strings.Contains(err.Error(), "could not write") {
    // fall back to stdout instead of file
    stdout, _, err = runKvstoreList(ctx, prefix)
}

Prevention

When it happens

Trigger: Calling the list command with two args where the second is a path that cannot be written: the target directory does not exist, the file exists but is not writable (permissions/ownership), the path is a directory, or the filesystem is read-only.

Common situations: Redirecting output to /etc/cilium/... in a container without write access; saving to a relative path after chdir; disk-full or read-only root filesystem in a Kubernetes node context.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/e0ee531cf7f67333. Report an issue: GitHub.