nektos/act · error
invalid property count for key 'credentials:'
Error message
invalid property count for key 'credentials:'
What it means
The job's `container.credentials:` map does not contain exactly two keys. act requires the map to hold precisely `username` and `password`; anything else — one key, three keys, or differently named keys — fails this check before any Docker registry authentication is attempted.
Source
Thrown at pkg/runner/run_context.go:1107
runID, _ = strconv.ParseInt(rid, 10, 64)
}
actionsRuntimeToken, _ = common.CreateAuthorizationToken(runID, runID, runID)
}
env["ACTIONS_RUNTIME_TOKEN"] = actionsRuntimeToken
}
func (rc *RunContext) handleCredentials(ctx context.Context) (string, string, error) {
// TODO: remove below 2 lines when we can release act with breaking changes
username := rc.Config.Secrets["DOCKER_USERNAME"]
password := rc.Config.Secrets["DOCKER_PASSWORD"]
container := rc.Run.Job().Container()
if container == nil || container.Credentials == nil {
return username, password, nil
}
if container.Credentials != nil && len(container.Credentials) != 2 {
err := fmt.Errorf("invalid property count for key 'credentials:'")
return "", "", err
}
ee := rc.NewExpressionEvaluator(ctx)
if username = ee.Interpolate(ctx, container.Credentials["username"]); username == "" {
err := fmt.Errorf("failed to interpolate container.credentials.username")
return "", "", err
}
if password = ee.Interpolate(ctx, container.Credentials["password"]); password == "" {
err := fmt.Errorf("failed to interpolate container.credentials.password")
return "", "", err
}
if container.Credentials["username"] == "" || container.Credentials["password"] == "" {
err := fmt.Errorf("container.credentials cannot be empty")
return "", "", err
}
View on GitHub (pinned to 4f41128141)
Solutions
- Make `credentials:` contain exactly `username:` and `password:` and nothing else.
- If you need to target a non-default registry, that is configured via the image reference or act flags, not extra credential keys.
- Re-check YAML indentation so no sibling keys are swallowed into the credentials map.
Example fix
# before
container:
image: registry.example.com/app
credentials:
username: ci
password: ${{ secrets.REG_PWD }}
registry: registry.example.com # third key -> error
# after
container:
image: registry.example.com/app
credentials:
username: ci
password: ${{ secrets.REG_PWD }} Defensive patterns
Strategy: validation
Validate before calling
# assert exactly two credential keys
python3 - <<'EOF'
import yaml,sys
wf=yaml.safe_load(open('.github/workflows/ci.yml'))
for j in wf.get('jobs',{}).values():
c=(j.get('container') or {}).get('credentials')
if c is not None and set(c)!= {'username','password'}:
sys.exit(f"bad credentials keys: {set(c)}")
EOF Prevention
- credentials maps only ever hold username and password.
- Automate this YAML check in CI lint.
When it happens
Trigger: `jobs.<id>.container.credentials:` in the workflow has extra keys, only one of username/password, or keys with different names; also triggered when YAML indentation folds another map under credentials.
Common situations: Adding a `server:` or `registry:` key next to username/password (GitHub only documents username/password); forgetting one half of the pair; pasting docker login CLI flags into the credentials block.
Related errors
- container.credentials cannot be empty
- failed to interpolate container.credentials.username
- failed to interpolate container.credentials.password
- ErrShortRef
- failed to handle credentials: %s
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/a6d13ce72dadb32b.
Report an issue: GitHub.