nektos/act · error

failed to fetch "%s" version "%s": %w

Error message

failed to fetch "%s" version "%s": %w

What it means

The action cache (configured via Config.ActionCache) failed to fetch the remote action repository at the given URL and ref. cache.Fetch resolves the repo/ref to a commit (cloning or API lookup depending on the implementation); any underlying git/network failure is wrapped with the repo URL and requested ref for context.

Source

Thrown at pkg/runner/step_action_remote.go:75

			return nil
		}

		for _, action := range sar.RunContext.Config.ReplaceGheActionWithGithubCom {
			if strings.EqualFold(fmt.Sprintf("%s/%s", sar.remoteAction.Org, sar.remoteAction.Repo), action) {
				sar.remoteAction.URL = "https://github.com"
				github.Token = sar.RunContext.Config.ReplaceGheActionTokenWithGithubCom
			}
		}
		if sar.RunContext.Config.ActionCache != nil {
			cache := sar.RunContext.Config.ActionCache

			var err error
			sar.cacheDir = fmt.Sprintf("%s/%s", sar.remoteAction.Org, sar.remoteAction.Repo)
			repoURL := sar.remoteAction.URL + "/" + sar.cacheDir
			repoRef := sar.remoteAction.Ref
			sar.resolvedSha, err = cache.Fetch(ctx, sar.cacheDir, repoURL, repoRef, github.Token)
			if err != nil {
				return fmt.Errorf("failed to fetch \"%s\" version \"%s\": %w", repoURL, repoRef, err)
			}

			remoteReader := func(ctx context.Context) actionYamlReader {
				return func(filename string) (io.Reader, io.Closer, error) {
					spath := path.Join(sar.remoteAction.Path, filename)
					for i := 0; i < maxSymlinkDepth; i++ {
						tars, err := cache.GetTarArchive(ctx, sar.cacheDir, sar.resolvedSha, spath)
						if err != nil {
							return nil, nil, os.ErrNotExist
						}
						treader := tar.NewReader(tars)
						header, err := treader.Next()
						if err != nil {
							return nil, nil, os.ErrNotExist
						}
						if header.FileInfo().Mode()&os.ModeSymlink == os.ModeSymlink {
							spath, err = symlinkJoin(spath, header.Linkname, ".")
							if err != nil {

View on GitHub (pinned to 4f41128141)

Solutions

  1. Check the wrapped error for the cause: 401/403 means token scope, 'could not read Username' means auth missing for a private repo, timeout/DNS means network.
  2. Pass a valid token: `act -s GITHUB_TOKEN=...` or the configured token input for private actions.
  3. Verify the ref exists on the target repository (tag spelled correctly, branch not deleted).
  4. For offline runs use `--action-offline-mode` after warming the cache once online; check proxy env vars (HTTP_PROXY/HTTPS_PROXY) reach github.com.

Example fix

# before: act push   (private action, no token)
# after
act push -s GITHUB_TOKEN=ghp_xxxx
Defensive patterns

Strategy: retry

Validate before calling

# pre-flight reachability + auth check
curl -fsS -H "Authorization: Bearer $GITHUB_TOKEN" \
  https://api.github.com/repos/org/action/commits/v4 >/dev/null \
  && echo ref-ok || echo 'ref missing or auth/network problem'

Try / catch

err := step.Prepare()(ctx)
if err != nil && strings.Contains(err.Error(), "failed to fetch") {
  // transient network/rate-limit: backoff and retry once
  time.Sleep(5 * time.Second)
  err = step.Prepare()(ctx)
}

Prevention

When it happens

Trigger: act runs with an ActionCache enabled (e.g. the Go-git-backed cache) and the fetch of 'https://github.com/{org}/{repo}' at ref (tag/branch/SHA) fails: network offline, DNS failure, private repo without a valid token, non-existent ref, or GitHub rate limiting.

Common situations: Running act without network access or behind a proxy; private action repos where GITHUB_TOKEN lacks access; typo'd tag (v5 when only v4 exists); rate-limited unauthenticated API; self-hosted GitHub with wrong server URL config.

Related errors


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