nektos/act · error
valid streams are STDIN, STDOUT and STDERR
Error message
valid streams are STDIN, STDOUT and STDERR
What it means
validateAttach checks each --attach value (lowercased) against the set {stdin, stdout, stderr}; anything else returns 'valid streams are STDIN, STDOUT and STDERR'. Attach options tell Docker which standard streams to hook up for the container, and those three are the only streams that exist, so the parser rejects unknown values early instead of sending an invalid request to the daemon.
Source
Thrown at pkg/container/docker_cli.go:1146
if isValid := validator(split[2]); !isValid {
return val, fmt.Errorf("bad mode specified: %s", mode)
}
val = fmt.Sprintf("%s:%s:%s", split[0], containerPath, mode)
}
if !path.IsAbs(containerPath) {
return val, fmt.Errorf("%s is not an absolute path", containerPath)
}
return val, nil
}
// validateAttach validates that the specified string is a valid attach option.
func validateAttach(val string) (string, error) {
s := strings.ToLower(val)
if slices.Contains([]string{"stdin", "stdout", "stderr"}, s) {
return s, nil
}
return val, errors.New("valid streams are STDIN, STDOUT and STDERR")
}
func toNetipAddrSlice(ips []string) []netip.Addr {
if len(ips) == 0 {
return nil
}
netIPs := make([]netip.Addr, 0, len(ips))
for _, ip := range ips {
addr, err := netip.ParseAddr(ip)
if err != nil {
continue
}
netIPs = append(netIPs, addr)
}
return netIPs
}
View on GitHub (pinned to 4f41128141)
Solutions
- Use only stdin, stdout, or stderr (any case): '--attach stderr'.
- Remove the --attach flag entirely if you did not intend it — act already wires up stdout/stderr for logging.
- Check the options string for typos introduced by YAML folding or quote stripping.
Example fix
# before container: image: node:20 options: --attach logs # after container: image: node:20 options: --attach stderr
Defensive patterns
Strategy: validation
Validate before calling
package main
import (
"fmt"
"strings"
)
func validateAttachOptions(options string) error {
fields := strings.Fields(options)
for i, f := range fields {
if f != "--attach" {
continue
}
if i+1 >= len(fields) {
return fmt.Errorf("--attach requires a value")
}
switch strings.ToLower(fields[i+1]) {
case "stdin", "stdout", "stderr":
default:
return fmt.Errorf("--attach %s invalid: only stdin/stdout/stderr allowed", fields[i+1])
}
}
return nil
} Try / catch
if err := runJob(ctx); err != nil {
if strings.Contains(err.Error(), "valid streams are STDIN, STDOUT and STDERR") {
return errors.New("remove or correct the --attach value in container options (stdin|stdout|stderr only)")
}
return err
} Prevention
- Use only stdin/stdout/stderr (case-insensitive) with --attach.
- Remember act already attaches stdout/stderr for logging; --attach is rarely needed.
- Do not confuse --attach with --log-driver or --publish.
When it happens
Trigger: A container options string like 'options: --attach logs' or '--attach STDIN,logs' where any element is not stdin/stdout/stderr (case-insensitive). Also values mangled by YAML quoting or shell-like splitting, e.g. '--attach stdin ' with a trailing token.
Common situations: Confusing --attach with --log-driver or --publish; passing a file/device name instead of a stream name; copy-paste from docker-compose 'attach' keys that expect a list and getting the syntax wrong in a single-line options string.
Related errors
- invalid storage option
- %s is not a valid mac address
- invalid logging opts for driver %s
- Cannot process container options: '%s': '%w'
- --pid: invalid PID mode
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/6610225e4ea20784.
Report an issue: GitHub.