{"record":{"id":"21aee239bac6e1d5","repo":"nektos/act","slug":"failed-to-handle-credentials-s","errorCode":null,"errorMessage":"failed to handle credentials: %s","messagePattern":"failed to handle credentials: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/runner/run_context.go","lineNumber":271,"sourceCode":"}\n\nfunc (rc *RunContext) startJobContainer() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\tlogger := common.Logger(ctx)\n\t\timage := rc.platformImage(ctx)\n\t\trawLogger := logger.WithField(\"raw_output\", true)\n\t\tlogWriter := common.NewLineWriter(rc.commandHandler(ctx), func(s string) bool {\n\t\t\tif rc.Config.LogOutput {\n\t\t\t\trawLogger.Infof(\"%s\", s)\n\t\t\t} else {\n\t\t\t\trawLogger.Debugf(\"%s\", s)\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\n\t\tusername, password, err := rc.handleCredentials(ctx)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to handle credentials: %s\", err)\n\t\t}\n\n\t\tlogger.Infof(\"\\U0001f680  Start image=%s\", image)\n\t\tname := rc.jobContainerName()\n\n\t\tenvList := make([]string, 0)\n\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_TOOL_CACHE\", \"/opt/hostedtoolcache\"))\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_OS\", \"Linux\"))\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_ARCH\", container.RunnerArch(ctx)))\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"RUNNER_TEMP\", \"/tmp\"))\n\t\tenvList = append(envList, fmt.Sprintf(\"%s=%s\", \"LANG\", \"C.UTF-8\")) // Use same locale as GitHub Actions\n\n\t\text := container.LinuxContainerEnvironmentExtensions{}\n\t\tbinds, mounts := rc.GetBindsAndMounts()\n\n\t\t// specify the network to which the container will connect when `docker create` stage. (like execute command line: docker create --network <networkName> <image>)\n\t\t// if using service containers, will create a new network for the containers.","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/runner/run_context.go#L253-L289","documentation":"startJobContainer resolves registry credentials for the job's container image via rc.handleCredentials, which interpolates the username/password expressions from workflow 'container.credentials' and (for GitHub-hosted images) can use GITHUB_TOKEN / CR_PAT style secrets. Failure is wrapped with '%s' (non-wrapping format) so the original cause text is appended verbatim.","triggerScenarios":"Job 'container: image: ...' block with 'credentials: username/password' whose expressions fail to evaluate, are empty, or reference missing secrets; handleCredentials returns an error when the image requires auth but no usable credentials resolve.","commonSituations":"Private registry (ghcr.io, ECR, Artifactory) image without passing secrets: act -s USERNAME=... -s PASSWORD=...; expression typo in credentials block; expired token.","solutions":["Pass the required secrets: act -s CR_USERNAME=user -s CR_PASSWORD=pass and reference them in container.credentials.","Verify the credential expressions in the workflow's 'container.credentials' interpolate to non-empty values.","Docker-login once on the host (docker login ghcr.io) so the image can be pulled without workflow-level credentials.","Check the appended cause text in the message — it names exactly which credential failed."],"exampleFix":"# before (workflow)\ncontainer:\n  image: ghcr.io/org/img:1\n  credentials:\n    username: ${{ secrets.CR_USER }}\n    password: ${{ secrets.CR_PASS }}\n# run without secrets\n\n# after\nact -s CR_USER=user -s CR_PASS=token -j build","handlingStrategy":"validation","validationCode":"# fail fast if required credential secrets are absent for jobs with container images\nfor s in CR_USERNAME CR_PASSWORD; do\n  [ -n \"${!s}\" ] || { echo \"missing secret $s\"; exit 1; }\ndone\ndocker login ghcr.io -u \"$CR_USERNAME\" -p \"$CR_PASSWORD\" >/dev/null && echo registry-auth-ok","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always invoke act with -s for every secret the workflow's container.credentials reference.","docker login on the host as a fallback so pulls need no workflow credentials.","Read the appended cause text — it names the failing credential."],"tags":["docker","registry","credentials","act"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}