nektos/act · error
--health-timeout cannot be negative
Error message
--health-timeout cannot be negative
What it means
Error [87]: After running a command in the container, act calls ExecInspect to fetch the exit code; that API call failed. Act cannot determine success/failure of the step command because the daemon did not answer the inspect request for the finished exec instance.
Source
Thrown at pkg/container/docker_cli.go:589
copts.healthTimeout != 0 ||
copts.healthStartPeriod != 0 ||
copts.healthRetries != 0 ||
copts.healthStartInterval != 0
if copts.noHealthcheck {
if haveHealthSettings {
return nil, errors.New("--no-healthcheck conflicts with --health-* options")
}
healthConfig = &container.HealthConfig{Test: []string{"NONE"}}
} else if haveHealthSettings {
var probe []string
if copts.healthCmd != "" {
probe = []string{"CMD-SHELL", copts.healthCmd}
}
if copts.healthInterval < 0 {
return nil, errors.New("--health-interval cannot be negative")
}
if copts.healthTimeout < 0 {
return nil, errors.New("--health-timeout cannot be negative")
}
if copts.healthRetries < 0 {
return nil, errors.New("--health-retries cannot be negative")
}
if copts.healthStartPeriod < 0 {
return nil, errors.New("--health-start-period cannot be negative")
}
if copts.healthStartInterval < 0 {
return nil, errors.New("--health-start-interval cannot be negative")
}
healthConfig = &container.HealthConfig{
Test: probe,
Interval: copts.healthInterval,
Timeout: copts.healthTimeout,
StartPeriod: copts.healthStartPeriod,
StartInterval: copts.healthStartInterval,
Retries: copts.healthRetries,View on GitHub (pinned to 4f41128141)
Solutions
- Check daemon health right after failure: docker info
- If proxying the socket (ssh/VPN), extend keepalive/idle timeouts
- Re-run the job; if reproducible only for long steps, shorten or split the step
- Update Docker Engine to match the moby API version act uses (or set DOCKER_API_VERSION)
Example fix
# before: idle ssh tunnel drops ssh -L /tmp/docker.sock:/var/run/docker.sock host & # after: keepalives on ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=6 -L /tmp/docker.sock:/var/run/docker.sock host &
Defensive patterns
Strategy: try-catch
Try / catch
if err != nil && strings.Contains(err.Error(), "failed to inspect exec") {
// command output already streamed; treat as inconclusive, re-run the step once
} Prevention
- Keep daemon connection alive during long steps (ServerAliveInterval on tunnels)
- Update Docker Engine alongside act upgrades
- Split very long steps so each exec finishes within proxy idle windows
When it happens
Trigger: cr.cli.ExecInspect erroring after waitForCommand completed: daemon connection lost right after command end, exec record garbage-collected by the daemon before inspection, or API version incompatibility on the exec inspect endpoint.
Common situations: Daemon restart racing the end of a step; remote DOCKER_HOST with connection drops under load; very long-running steps where intermediate proxies (ssh -L, VPN) close idle streams.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- --uts: invalid UTS mode
- --userns: invalid USER mode
- --health-interval cannot be negative
- --health-retries cannot be negative
- --health-start-period cannot be negative
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/bf5581d2cb5bf23f.
Report an issue: GitHub.