golang/go · error

reading %s: %v

Error message

reading %s: %v

What it means

While scanning Go source files for import declarations (during go list, go build, go test, or imports.ScanDir/ScanFiles), the toolchain opens each .go file and calls ReadImports to parse it. If the read fails for any reason — I/O error, encoding problem, truncated content — the underlying error is wrapped with the filename in this message.

Source

Thrown at src/cmd/go/internal/imports/scan.go:62

func ScanFiles(files []string, tags map[string]bool) ([]string, []string, error) {
	return scanFiles(files, tags, true)
}

func scanFiles(files []string, tags map[string]bool, explicitFiles bool) ([]string, []string, error) {
	imports := make(map[string]bool)
	testImports := make(map[string]bool)
	numFiles := 0
Files:
	for _, name := range files {
		r, err := fsys.Open(name)
		if err != nil {
			return nil, nil, err
		}
		var list []string
		data, err := ReadImports(r, false, &list)
		r.Close()
		if err != nil {
			return nil, nil, fmt.Errorf("reading %s: %v", name, err)
		}

		// import "C" is implicit requirement of cgo tag.
		// When listing files on the command line (explicitFiles=true)
		// we do not apply build tag filtering but we still do apply
		// cgo filtering, so no explicitFiles check here.
		// Why? Because we always have, and it's not worth breaking
		// that behavior now.
		for _, path := range list {
			if path == `"C"` && !tags["cgo"] && !tags["*"] {
				continue Files
			}
		}

		if !explicitFiles && !ShouldBuild(data, tags) {
			continue
		}
		numFiles++

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Check the file named in the error message — verify it exists and is readable (ls -la, cat).
  2. Examine the underlying error (the %v portion) for the specific cause: permission denied, I/O error, EOF, etc.
  3. If the file is corrupted or truncated, restore it from version control (git checkout -- <file>).
  4. Re-run the build after fixing the file; transient filesystem errors may resolve on retry.
Defensive patterns

Strategy: try-catch

Validate before calling

// Check file readability before invoking the build.
func checkGoFilesReadable(dir string) error {
    entries, err := os.ReadDir(dir)
    if err != nil {
        return err
    }
    for _, e := range entries {
        if !strings.HasSuffix(e.Name(), ".go") {
            continue
        }
        f, err := os.Open(filepath.Join(dir, e.Name()))
        if err != nil {
            return fmt.Errorf("cannot open %s: %w", e.Name(), err)
        }
        f.Close()
    }
    return nil
}

Try / catch

// When using imports.ScanDir or go/packages programmatically:
files, err := imports.ScanDir(dir, tags)
if err != nil {
    if strings.HasPrefix(err.Error(), "reading") {
        // I/O or encoding error on a specific file
        log.Printf("source file read failure: %v", err)
        // optionally: identify and report the problematic file, restore from VCS
    }
    return err
}

Prevention

When it happens

Trigger: A .go file passes the directory listing filter but fails when opened and read by fsys.Open + ReadImports. The file handle is closed before the error is returned. Causes include file permission changes between directory listing and read, non-UTF-8 encoding, truncated/corrupted files, or concurrent file deletion.

Common situations: Files modified or deleted by another process (IDE, formatter, linter) during a build. Permission restrictions on certain files in shared environments. Corrupted source files from a failed git checkout or network filesystem issue. NFS or SSHFS I/O errors.

Related errors


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