hashicorp/terraform · error
cannot search %s: %s
Error message
cannot search %s: %s
What it means
Raised inside the filepath.Walk callback in SearchLocalDirectory (internal/getproviders/filesystem_search.go:51). When the walk cannot access a path (the 'err' argument to the visit function is non-nil), it is wrapped as 'cannot search <path>: <err>'. Causes include permission denied, a broken/dangling symlink in the hierarchy, or the directory disappearing mid-walk. The error aborts the whole scan.
Source
Thrown at internal/getproviders/filesystem_search.go:51
// potentially keep their plugins in a non-standard location but use a
// symlink to help Terraform find them anyway.
originalBaseDir := baseDir
if finalDir, err := filepath.EvalSymlinks(baseDir); err == nil {
if finalDir != filepath.Clean(baseDir) {
log.Printf("[TRACE] getproviders.SearchLocalDirectory: using %s instead of %s", finalDir, baseDir)
}
baseDir = finalDir
} else {
// We'll eat this particular error because if we're somehow able to
// find plugins via baseDir below anyway then we'd rather do that than
// hard fail, but we'll log it in case it's useful for diagnosing why
// discovery didn't produce the expected outcome.
log.Printf("[TRACE] getproviders.SearchLocalDirectory: failed to resolve symlinks for %s: %s", baseDir, err)
}
err := filepath.Walk(baseDir, func(fullPath string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("cannot search %s: %s", fullPath, err)
}
// There are two valid directory structures that we support here...
// Unpacked: registry.terraform.io/hashicorp/aws/2.0.0/linux_amd64 (a directory)
// Packed: registry.terraform.io/hashicorp/aws/terraform-provider-aws_2.0.0_linux_amd64.zip (a file)
//
// Both of these give us enough information to identify the package
// metadata.
fsPath, err := filepath.Rel(baseDir, fullPath)
if err != nil {
// This should never happen because the filepath.Walk contract is
// for the paths to include the base path.
log.Printf("[TRACE] getproviders.SearchLocalDirectory: ignoring malformed path %q during walk: %s", fullPath, err)
return nil
}
relPath := filepath.ToSlash(fsPath)
parts := strings.Split(relPath, "/")
View on GitHub (pinned to c9def3e214)
Solutions
- Fix filesystem permissions so the Terraform process can read the entire mirror tree (e.g. chmod -R +rX on the mirror directory).
- Find and remove or repair dangling symlinks in the mirror hierarchy.
- Confirm the mirror directory path configured in the CLI config actually exists and is stable during the scan.
- If a path is intentionally inaccessible, exclude it or move the mirror to a clean location.
Example fix
# before: mirror dir not readable by terraform process # after chmod -R a+rX /opt/terraform-plugins
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the mirror directory is walkable before scanning.
func walkable(dir string) error {
info, err := os.Stat(dir)
if err != nil {
return err
}
if !info.IsDir() {
return fmt.Errorf("%s is not a directory", dir)
}
// Attempt a representative read to surface permission errors early.
f, err := os.Open(dir)
if err != nil {
return err
}
f.Close()
return nil
} Try / catch
found, err := getproviders.SearchLocalDirectory(mirrorDir)
if err != nil {
return fmt.Errorf("cannot scan provider mirror %s (check permissions/symlinks): %w", mirrorDir, err)
} Prevention
- Ensure the Terraform process has read+execute permissions across the whole mirror tree.
- Remove dangling symlinks from the mirror hierarchy (only the top-level dir may be a symlink).
- Point the mirror at a stable local directory, not a flaky network mount.
When it happens
Trigger: Scanning a filesystem provider mirror directory that contains a path Go's walker cannot stat or read: a dangling symlink, a permission-restricted subdirectory, or a path deleted during the walk. Triggered by any terraform init / provider discovery that uses a local mirror.
Common situations: A plugin filesystem mirror (CLI plugin_cache_dir or filesystem_mirror) with restrictive permissions; a broken symlink left by a failed download; a network mount that dropped mid-scan.
Related errors
- Cannot read directory %s
- error deleting workspace %s: %w
- Error reading %s: %s
- cannot read %s: %s
- cannot create temporary file to update credentials: %s
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/6b16611a4ac1e9c1.
Report an issue: GitHub.