docker/cli · error
invalid field ' ' must be a key=value pair
Error message
invalid field '%s' must be a key=value pair
What it means
Thrown by SecretOpt.Set (secret.go:46) when a field in the long-syntax --secret value is not a key=value pair or has an empty key. Mirrors the config logic: long syntax expects source=NAME,target=/path,uid=...,gid=...,mode=0440; a bare token or missing '=' is rejected. The simple `--secret NAME` shorthand only applies for a single field with no '='.
Solutions
- Write every field as key=value: `--secret source=db_pw,target=/run/secrets/db,mode=0400`.
- For the simple case use shorthand: `--secret db_pw`.
- Ensure each field has a non-empty key before '='.
- If a value is optional, still provide it explicitly (e.g. target=/default/path).
Example fix
// before --secret source=db_pw,target // after --secret source=db_pw,target=/run/secrets/db_pw
Defensive patterns
Strategy: validation
Validate before calling
// Verify every CSV field of a --secret value is key=value with a non-empty key.
for _, f := range strings.Split(secretVal, ",") {
k, _, ok := strings.Cut(strings.TrimSpace(f), "=")
if !ok || k == "" {
return fmt.Errorf("secret field %q must be key=value", f)
}
} Prevention
- Use the simple `--secret NAME` shorthand when you only need a name.
- Always pair every key with a value via '='.
- Avoid trailing commas that produce empty fields.
- Build --secret strings field-by-field, not by comma-joining partials.
When it happens
Trigger: Passing `--secret source=db_pw,target` (target lacks value), `--secret foo,bar` (bar has no '='), `--secret =x` (empty key). strings.Cut at line 44 returns ok=false or empty key.
Common situations: Mixing positional and key=value syntax, forgetting '=' for target/mode, copy-paste truncation, or building the --secret string with a missing value.
Related errors
- invalid field ' ' must be a key=value pair
- invalid field in config request
- when using secret driver secret data must be empty
- error reading from STDIN: data is empty
- secret file is required
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/585604bbd5ef1abf.
Report an issue: GitHub.
Appendix: source
Thrown at opts/swarmopts/secret.go:46
File: &swarm.SecretReferenceFileTarget{
UID: "0",
GID: "0",
Mode: 0o444,
},
}
// support a simple syntax of --secret foo
if len(fields) == 1 && !strings.Contains(fields[0], "=") {
options.File.Name = fields[0]
options.SecretName = fields[0]
o.values = append(o.values, options)
return nil
}
for _, field := range fields {
key, val, ok := strings.Cut(field, "=")
if !ok || key == "" {
return fmt.Errorf("invalid field '%s' must be a key=value pair", field)
}
// TODO(thaJeztah): these options should not be case-insensitive.
switch strings.ToLower(key) {
case "source", "src":
options.SecretName = val
case "target":
options.File.Name = val
case "uid":
options.File.UID = val
case "gid":
options.File.GID = val
case "mode":
m, err := strconv.ParseUint(val, 0, 32)
if err != nil {
return fmt.Errorf("invalid mode specified: %v", err)
}
options.File.Mode = os.FileMode(m)View on GitHub (pinned to 4f84911bfe)