nektos/act · error
invalid storage option
Error message
invalid storage option
What it means
parseStorageOpts splits each --storage-opt entry on the first '=' using strings.Cut; an entry without an '=' character cannot form a key/value pair and is rejected outright with 'invalid storage option'. This mirrors the Docker CLI's own validation, so anything docker run would reject also fails at act's parse layer before the container is created.
Source
Thrown at pkg/container/docker_cli.go:994
for _, opt := range securityOpts {
if opt == "systempaths=unconfined" {
maskedPaths = []string{}
readonlyPaths = []string{}
} else {
filtered = append(filtered, opt)
}
}
return filtered, maskedPaths, readonlyPaths
}
// parses storage options per container into a map
func parseStorageOpts(storageOpts []string) (map[string]string, error) {
m := make(map[string]string)
for _, option := range storageOpts {
k, v, ok := strings.Cut(option, "=")
if !ok {
return nil, errors.New("invalid storage option")
}
m[k] = v
}
return m, nil
}
// parseDevice parses a device mapping string to a container.DeviceMapping struct
func parseDevice(device, serverOS string) (container.DeviceMapping, error) {
switch serverOS {
case "linux":
return parseLinuxDevice(device)
case "windows":
// Windows doesn't support mapping, so passing the given value as-is.
return container.DeviceMapping{PathOnHost: device}, nil
default:
return container.DeviceMapping{}, fmt.Errorf("unknown server OS: %s", serverOS)
}
}View on GitHub (pinned to 4f41128141)
Solutions
- Rewrite the option in key=value form: '--storage-opt size=10G'.
- Verify YAML quoting of the options line so '=' survives parsing (quote the whole string in single quotes).
- Confirm the key is valid for your storage driver (size only works on overlay2 with pquota, btrfs, zfs, devicethrow); an invalid key with correct syntax will instead be rejected by the daemon.
- Remove stray/duplicate --storage-opt flags that parse to empty strings.
Example fix
# before container: image: node:20 options: --storage-opt size # after container: image: node:20 options: --storage-opt size=10G
Defensive patterns
Strategy: validation
Validate before calling
package main
import (
"fmt"
"strings"
)
func validateStorageOpts(options string) error {
for i, f := range strings.Fields(options) {
if f == "--storage-opt" {
if i+1 >= len(strings.Fields(options)) || !strings.Contains(strings.Fields(options)[i+1], "=") {
return fmt.Errorf("--storage-opt requires key=value (got no '=' in next token)")
}
}
if v, ok := strings.CutPrefix(f, "--storage-opt="); ok && !strings.Contains(v, "=") {
return fmt.Errorf("--storage-opt=%q lacks '='", v)
}
}
return nil
} Try / catch
if err := exec.NewContainerExecutor(...)(ctx); err != nil {
if strings.Contains(err.Error(), "invalid storage option") {
return fmt.Errorf("fix container options: each --storage-opt must be key=value: %w", err)
}
return err
} Prevention
- Always write storage options as --storage-opt key=value.
- Quote the full options string in YAML so '=' survives parsing.
- Confirm the key is supported by your storage driver (size works on overlay2+pquota, btrfs, zfs).
When it happens
Trigger: A container options string containing a bare flag-style storage option, e.g. 'options: --storage-opt size' (missing '=10G'), or a trailing empty entry like '--storage-opt ' after shell-style splitting. Any element of the parsed storageOpts slice that contains no '=' character.
Common situations: Typing '--storage-opt size' instead of '--storage-opt size=10G' on overlay2/btrfs/zfs drivers; copy-pasting options where the value was dropped; quoting mistakes in YAML that strip the '=value' part during shell-like splitting of the options line.
Related errors
- valid streams are STDIN, STDOUT and STDERR
- %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/6bf48bd174de64a8.
Report an issue: GitHub.