docker/cli · error
invalid type %T for map[string]string
Error message
invalid type %T for map[string]string
What it means
Thrown by transformMapStringString, the transformer for fields like `sysctls`, `labels`, `extra_hosts` (mapping form). The value must be a `map[string]any` (YAML mapping) or `map[string]string`; any other shape (scalar, sequence) is rejected.
Solutions
- Provide a mapping: `sysctls: { net.core.somaxconn: 1024 }`.
- For list-style fields use the list form only where supported (some fields accept both via a different transformer).
Example fix
# before
web:
sysctls: net.core.somaxconn
# after
web:
sysctls:
net.core.somaxconn: "1024" Defensive patterns
Strategy: type-guard
Validate before calling
func validateMapStringString(field string, v any) error {
switch v.(type) {
case map[string]any, map[string]string:
return nil
default:
return fmt.Errorf("%s must be a mapping, got %T", field, v)
}
} Type guard
func isStringMapping(v any) bool {
switch v.(type) {
case map[string]any, map[string]string:
return true
}
return false
} Prevention
- Remember `sysctls`/`labels`/`extra_hosts`(map form) need key:value pairs.
- Use `docker compose config` to render and check.
- Watch indentation: a mapping must be more indented than its parent key.
When it happens
Trigger: A field expecting a mapping is given a scalar or a list — e.g. `sysctls: net.core.somaxconn` (a single string) or `labels: [a,b]`. The transformer is invoked per-key during Transform().
Common situations: Forgetting the value side of a mapping; using a list where a map is required; typo in indentation.
Related errors
- invalid type %T for ulimits
- invalid type %T for port
- invalid type %T for secret
- invalid type %T for service build
- invalid type %T for service volume
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/a44b03dc46d65b10.
Report an issue: GitHub.
Appendix: source
Thrown at cli/compose/loader/loader.go:692
return obj, nil
}
func absPath(workingDir string, filePath string) string {
if filepath.IsAbs(filePath) {
return filePath
}
return filepath.Join(workingDir, filePath)
}
var transformMapStringString TransformerFunc = func(data any) (any, error) {
switch value := data.(type) {
case map[string]any:
return toMapStringString(value, false), nil
case map[string]string:
return value, nil
default:
return data, fmt.Errorf("invalid type %T for map[string]string", value)
}
}
var transformExternal TransformerFunc = func(data any) (any, error) {
switch value := data.(type) {
case bool:
return map[string]any{"external": value}, nil
case map[string]any:
return map[string]any{"external": true, "name": value["name"]}, nil
default:
return data, fmt.Errorf("invalid type %T for external", value)
}
}
var transformServicePort TransformerFunc = func(data any) (any, error) {
switch entries := data.(type) {
case []any:
// We process the list instead of individual items here.View on GitHub (pinned to 4f84911bfe)