golang/go · error

read %s: %v

Error message

read %s: %v

What it means

Wrapped I/O error from getFileInfo during module-index building: the lower-level readGoInfo (for .go files) or readComments (for non-.go files with a recognized extension) returned an error reading the file's bytes. The %s is the joined file path (dir/name) and %v is the underlying error (e.g. permission denied, truncated file).

Source

Thrown at src/cmd/go/internal/modindex/build.go:274

	f, err := fsys.Open(info.name)
	if err != nil {
		return nil, err
	}

	// TODO(matloob) should we decide whether to ignore binary only here or earlier
	// when we create the index file?
	var ignoreBinaryOnly bool
	if strings.HasSuffix(name, ".go") {
		err = readGoInfo(f, info)
		if strings.HasSuffix(name, "_test.go") {
			ignoreBinaryOnly = true // ignore //go:binary-only-package comments in _test.go files
		}
	} else {
		info.header, err = readComments(f)
	}
	f.Close()
	if err != nil {
		return nil, fmt.Errorf("read %s: %v", info.name, err)
	}

	// Look for +build comments to accept or reject the file.
	info.goBuildConstraint, info.plusBuildConstraints, info.binaryOnly, err = getConstraints(info.header)
	if err != nil {
		return nil, fmt.Errorf("%s: %v", name, err)
	}

	if ignoreBinaryOnly && info.binaryOnly {
		info.binaryOnly = false // override info.binaryOnly
	}

	return info, nil
}

func cleanDecls(m map[string][]token.Position) ([]string, map[string][]token.Position) {
	all := make([]string, 0, len(m))
	for path := range m {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Check the file shown in the message: `ls -l <path>` and `cat <path>` to confirm it exists and is readable.
  2. Fix permissions: `chmod -R u+r <module-dir>` or re-run as a user with read access.
  3. Clear and re-download the module: `go clean -modcache && go mod download` to discard a corrupted cache entry.
  4. If the file is being written by another process, wait for it to finish before triggering a build.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight check that every .go file is readable before triggering the index build.
func filesReadable(dir string) error {
    return filepath.WalkDir(dir, func(p string, d fs.DirEntry, err error) error {
        if err != nil {
            return err
        }
        if d.IsDir() || !strings.HasSuffix(p, ".go") {
            return nil
        }
        f, err := os.Open(p)
        if err != nil {
            return fmt.Errorf("unreadable %s: %w", p, err)
        }
        f.Close()
        return nil
    })
}

Try / catch

// go/build and the module index surface read errors as standard errors;
// wrap the call to add context for end users.
pkg, err := modindex.OpenPackage(modroot, dir)
if err != nil {
    var pathErr *fs.PathError
    if errors.As(err, &pathErr) {
        // permission / ENOENT: surface to the user, optionally clear cache.
        return fmt.Errorf("source unreadable (%s) — check perms or run `go clean -modcache`", pathErr.Path)
    }
    return err
}

Prevention

When it happens

Trigger: Indexing a module whose .go or other recognized source file is unreadable: readGoInfo hits a parse/scan error, readComments fails, or fsys.Open succeeded but the subsequent read failed. Reached from getFileInfo in modindex/build.go when err != nil after f.Close().

Common situations: File permissions on a checked-out source file are too restrictive; a .go file is mid-write (truncated) when the index is regenerated; filesystem corruption or a broken symlink inside the module cache (GOMODCACHE).

Related errors


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