golang/go · error

error opening target for caching: %w

Error message

error opening target for caching: %w

What it means

In pgoActor.Act, after the preprofile tool writes a preprocessed PGO profile to a.Target, the actor opens it to insert into the build cache. If os.Open(a.Target) fails, the error is wrapped with %w and returned. This is an internal post-build step for PGO (-pgoprofile) inputs.

Source

Thrown at src/cmd/go/internal/work/action.go:512

	if err := sh.run(".", p.input, nil, cfg.BuildToolexec, base.Tool("preprofile"), "-o", a.Target, "-i", p.input); err != nil {
		return err
	}

	// N.B. Builder.build looks for the out in a.built, regardless of
	// whether this came from cache.
	a.built = a.Target

	if !cfg.BuildN {
		// Cache the output.
		//
		// N.B. We don't use updateBuildID here, as preprocessed PGO profiles
		// do not contain a build ID. updateBuildID is typically responsible
		// for adding to the cache, thus we must do so ourselves instead.

		r, err := os.Open(a.Target)
		if err != nil {
			return fmt.Errorf("error opening target for caching: %w", err)
		}

		c := cache.Default()
		outputID, _, err := c.Put(a.actionID, r)
		r.Close()
		if err != nil {
			return fmt.Errorf("error adding target to cache: %w", err)
		}
		if cfg.BuildX {
			sh.ShowCmd("", "%s # internal", joinUnambiguously(str.StringList("cp", a.Target, c.OutputFile(outputID))))
		}
	}

	return nil
}

type coverProvider struct {
	// name of static metadata file fragment emitted by the cover

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Check dmesg/syslog for the file removal (antivirus, container ephemeral fs).
  2. Ensure GOCACHE and the build temp dir are on a stable writable filesystem.
  3. Re-run the build; if transient, it succeeds; if not, inspect a.Target path length and permissions.
  4. Run with -x to see the exact target path produced by preprofile.

Example fix

// before
$ go build -pgoprofile=cpu.pprof ./...
// error: error opening target for caching: open /tmp/.../b001/pprof: no such file

// after — point GOCACHE at a stable local dir
$ export GOCACHE=$HOME/.cache/go-build
$ go build -x -pgoprofile=cpu.pprof ./...
Defensive patterns

Strategy: validation

Validate before calling

// Sanity-check the preprofile output exists before caching.
func verifyPgoTarget(path string) error {
    fi, err := os.Stat(path)
    if err != nil { return fmt.Errorf("PGO target missing: %w", err) }
    if fi.Size() == 0 { return fmt.Errorf("PGO target empty: %s", path) }
    return nil
}

Prevention

When it happens

Trigger: Running 'go build -pgoprofile=<pprof>' where the preprofile tool reported success but the output file is missing or unreadable when caching begins. Typically an interrupted build, a full tmpdir, or antivirus removing the file.

Common situations: Antivirus/quarantine removing the freshly written intermediate; TMPDIR/GOCACHE on a flaky mount; the file was on a path that exceeded a length limit and wasn't actually created.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/1b91792ac7b43c40. Report an issue: GitHub.