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

  1. Make `credentials:` contain exactly `username:` and `password:` and nothing else.
  2. If you need to target a non-default registry, that is configured via the image reference or act flags, not extra credential keys.
  3. 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

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


AI-assisted analysis of nektos/act@4f41128141 (2026-08-15). Data as JSON: /api/errors/a6d13ce72dadb32b. Report an issue: GitHub.