nektos/act · error

failed to interpolate credentials.username

Error message

failed to interpolate credentials.username

What it means

Interpolating a service container's `credentials.username` produced an empty string. After the two-key check passes, the value is run through the expression evaluator; empty output (missing secret or empty literal) aborts service startup.

Source

Thrown at pkg/runner/run_context.go:1140

		err := fmt.Errorf("container.credentials cannot be empty")
		return "", "", err
	}

	return username, password, nil
}

func (rc *RunContext) handleServiceCredentials(ctx context.Context, creds map[string]string) (username, password string, err error) {
	if creds == nil {
		return
	}
	if len(creds) != 2 {
		err = fmt.Errorf("invalid property count for key 'credentials:'")
		return
	}

	ee := rc.NewExpressionEvaluator(ctx)
	if username = ee.Interpolate(ctx, creds["username"]); username == "" {
		err = fmt.Errorf("failed to interpolate credentials.username")
		return
	}

	if password = ee.Interpolate(ctx, creds["password"]); password == "" {
		err = fmt.Errorf("failed to interpolate credentials.password")
		return
	}

	return
}

// GetServiceBindsAndMounts returns the binds and mounts for the service container, resolving paths as appropriate
func (rc *RunContext) GetServiceBindsAndMounts(svcVolumes []string) ([]string, map[string]string) {
	if rc.Config.ContainerDaemonSocket == "" {
		rc.Config.ContainerDaemonSocket = "/var/run/docker.sock"
	}
	binds := []string{}
	if rc.Config.ContainerDaemonSocket != "-" {

View on GitHub (pinned to 4f41128141)

Solutions

  1. Pass the secret via `act -s <NAME>=<value>` or `--secret-file`.
  2. Verify the secret name matches exactly (case-sensitive).
  3. If the service image is public, drop the credentials block — it is only needed for private registries.

Example fix

# before
services:
  db:
    image: private.example.com/pg
    credentials: { username: '${{ secrets.PG_USER }}', password: 'x' }
# run: act push   (secret missing -> empty username)
# after
act push -s PG_USER=ci -s PG_PWD=secret
Defensive patterns

Strategy: validation

Validate before calling

act --secret-file .secrets --dryrun  # confirms all referenced secrets are provided

Prevention

When it happens

Trigger: `services.<id>.credentials.username:` is `${{ secrets.X }}` where X was not supplied to act, or is an empty literal.

Common situations: Private-registry service images requiring auth the local act run never provides; secret name mismatch; secrets file not loaded.

Related errors


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