nektos/act · warning

broken file: %v != %v

Error message

broken file: %v != %v

What it means

Storage.Commit concatenates the uploaded temp chunk files into the final cache file and compares total bytes written against the size the client declared when finalizing the cache entry. A mismatch means the stored chunks do not add up to the declared size, so act removes the incomplete file and fails the commit — the cache upload is treated as broken/interrupted. Size < 0 (unknown size, actions/cache@v2) skips the check.

Source

Thrown at pkg/artifactcache/storage.go:89

		f, err := os.Open(v)
		if err != nil {
			return 0, err
		}
		n, err := io.Copy(file, f)
		_ = f.Close()
		if err != nil {
			return 0, err
		}
		written += n
	}

	// If size is less than 0, it means the size is unknown.
	// We can't check the size of the file, just skip the check.
	// It happens when the request comes from old versions of actions, like `actions/cache@v2`.
	if size >= 0 && written != size {
		_ = file.Close()
		_ = os.Remove(name)
		return 0, fmt.Errorf("broken file: %v != %v", written, size)
	}

	return written, nil
}

func (s *Storage) Serve(w http.ResponseWriter, r *http.Request, id uint64) {
	name := s.filename(id)
	http.ServeFile(w, r, name)
}

func (s *Storage) Remove(id uint64) {
	_ = os.Remove(s.filename(id))
	_ = os.RemoveAll(s.tempDir(id))
}

func (s *Storage) filename(id uint64) string {
	return filepath.Join(s.rootDir, fmt.Sprintf("%02x", id%0xff), fmt.Sprint(id))
}

View on GitHub (pinned to 4f41128141)

Solutions

  1. Simply rerun the workflow — the failed commit is cleaned up and a fresh upload usually succeeds
  2. Clear the cache server temp dir (~/.cache/act/actcache*/_tmp/ inside the cache dir) if stale chunks persist
  3. Ensure only one run uploads a given cache key at a time
  4. If persistent, verify disk health and free space on the cache volume
Defensive patterns

Strategy: retry

Try / catch

written, err := storage.Commit(id, size)
if err != nil && strings.HasPrefix(err.Error(), "broken file") {
    // upload integrity broke; discard and retry the whole upload
    storage.Remove(id)
    return retryUpload()
}
return written, err

Prevention

When it happens

Trigger: Finalizing a cache upload (POST /caches) where chunks were lost, duplicated, or partially written before commit — e.g. a PATCH chunk failed silently, a previous partial commit left stale temp files, or the declared size was computed before the content changed.

Common situations: Network hiccup or client abort during chunk upload on the local loopback proxy; two uploads racing for the same cache id; act killed during upload leaving stale temp chunks that get mixed into a later commit; flaky disk.

Related errors


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