docker/cli · error
invalid type %T for port
Error message
invalid type %T for port
What it means
Thrown by transformServicePort in its per-entry loop. When `ports` is a list, each element must be an int, a string (short syntax), or a map (long syntax). Any other element type (bool, nested list, null) hits this default branch.
Solutions
- Make each entry an int (`80`), a string (`"8080:80"`), or a map (`{ target: 80, published: 8080 }`).
- Remove stray/null entries introduced by templating.
Example fix
# before
web:
ports:
- 80
- [81]
# after
web:
ports:
- 80
- 81 Defensive patterns
Strategy: type-guard
Validate before calling
func validatePortEntries(ports any) error {
list, ok := ports.([]any)
if !ok {
return nil // outer error 469 handles non-list
}
for i, e := range list {
switch e.(type) {
case int, string, map[string]any:
default:
return fmt.Errorf("ports[%d]: invalid type %T", i, e)
}
}
return nil
} Type guard
func isPortEntry(v any) bool {
switch v.(type) {
case int, string, map[string]any:
return true
}
return false
} Prevention
- Keep each ports entry an int, string, or long-form map.
- Avoid nested lists or nulls from templating.
- Render with `docker compose config` to spot malformed entries.
When it happens
Trigger: A service has `ports:` as a list containing a non-port element, e.g. `ports: [80, [81]]`, `ports: [true]`, or `ports: [~]`.
Common situations: Bad indentation turning a map into a nested list; templating that injects nulls; mixing port and label entries.
Related errors
- invalid type %T for ulimits
- invalid type %T for map[string]string
- 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/d9bcd916881cefe4.
Report an issue: GitHub.
Appendix: source
Thrown at cli/compose/loader/loader.go:731
ports := []any{}
for _, entry := range entries {
switch value := entry.(type) {
case int:
v, err := toServicePortConfigs(strconv.Itoa(value))
if err != nil {
return data, err
}
ports = append(ports, v...)
case string:
v, err := toServicePortConfigs(value)
if err != nil {
return data, err
}
ports = append(ports, v...)
case map[string]any:
ports = append(ports, value)
default:
return data, fmt.Errorf("invalid type %T for port", value)
}
}
return ports, nil
default:
return data, fmt.Errorf("invalid type %T for port", entries)
}
}
var transformStringSourceMap TransformerFunc = func(data any) (any, error) {
switch value := data.(type) {
case string:
return map[string]any{"source": value}, nil
case map[string]any:
return data, nil
default:
return data, fmt.Errorf("invalid type %T for secret", value)
}
}View on GitHub (pinned to 4f84911bfe)