nektos/act · error
invalid publish opts format (should be name=value but got '%
Error message
invalid publish opts format (should be name=value but got '%s')
What it means
convertToStandardNotation converts Docker's long publish syntax (-p published=8080,target=80,protocol=tcp) into the standard host:container/proto form. Each comma-separated parameter must contain '=' with a non-empty key; a fragment like '8080' or '=tcp' (empty key) fails with this error before the container is created.
Source
Thrown at pkg/container/docker_cli.go:915
if ep.MacAddress != "" {
ma, err := net.ParseMAC(strings.TrimSpace(ep.MacAddress))
if err != nil {
return nil, fmt.Errorf("%s is not a valid mac address", ep.MacAddress)
}
epConfig.MacAddress = network.HardwareAddr(ma)
}
return epConfig, nil
}
func convertToStandardNotation(ports []string) ([]string, error) {
optsList := []string{}
for _, publish := range ports {
if strings.Contains(publish, "=") {
params := map[string]string{"protocol": "tcp"}
for param := range strings.SplitSeq(publish, ",") {
k, v, ok := strings.Cut(param, "=")
if !ok || k == "" {
return optsList, fmt.Errorf("invalid publish opts format (should be name=value but got '%s')", param)
}
params[k] = v
}
optsList = append(optsList, fmt.Sprintf("%s:%s/%s", params["published"], params["target"], params["protocol"]))
} else {
optsList = append(optsList, publish)
}
}
return optsList, nil
}
func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]string, error) {
loggingOptsMap := opts.ConvertKVStringsToMap(loggingOpts)
if loggingDriver == "none" && len(loggingOpts) > 0 {
return map[string]string{}, fmt.Errorf("invalid logging opts for driver %s", loggingDriver)
}
return loggingOptsMap, nil
}View on GitHub (pinned to 4f41128141)
Solutions
- Use the standard form -p 8080:80/tcp, or the fully-formed long syntax -p published=8080,target=80,protocol=tcp
- Remove stray '=' characters from port values and trailing commas
- Check YAML folded scalars for accidental line-join artifacts
Example fix
# before options: -p localhost:8080=80 # after options: -p 8080:80
Defensive patterns
Strategy: validation
Validate before calling
for _, p := range ports {
if strings.Contains(p, "=") {
for _, param := range strings.Split(p, ",") {
k, _, ok := strings.Cut(param, "=")
if !ok || k == "" {
return fmt.Errorf("bad long-syntax publish %q", p)
}
}
}
} Prevention
- Default to the short -p host:container[/proto] form
- Any '=' in a -p value selects the long parser — avoid stray equals
- No trailing commas in long-syntax lists
When it happens
Trigger: Passing -p/--publish with '=' present in the value (which routes it to the long-syntax parser) but a malformed list: '-p 8080=,target=80', '-p =8080,target=80', or a stray trailing comma producing an empty-ish param. Note any '=' anywhere in the -p value selects the long format, so 'localhost:8080=80' also trips it.
Common situations: Copy-pasting URL-ish or key=value strings into -p; mixing legacy ':=' style; trailing commas in YAML folded option strings; assuming act accepts docker-compose port mappings.
Related errors
- invalid range format for --expose: %w
- --cgroupns: invalid CGROUP mode
- parse %q: %w
- %s is not a valid mac address
- invalid value: %d. Valid memory swappiness range is 0-100
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/67c2ee4fe626e841.
Report an issue: GitHub.