kubernetes/kops · error

reading tree: %w

Error message

reading tree: %w

What it means

After building the directory path, srcPath.ReadTree(ctx) enumerates all objects under the prefix. If the tree read fails — prefix missing, listing permission denied, backend error — the failure is wrapped as 'reading tree: %w' and bootstrap-data building stops.

Source

Thrown at pkg/commands/toolbox_enroll.go:906

			*pSrc = dest
			return nil
		}

		// remapTree remaps a file tree from s3/gcs etc to the local file system on the target node.
		remapTree := func(pSrc *string, dest string) error {
			src := *pSrc
			if !strings.HasPrefix(src, remapPrefix) {
				return nil
			}

			srcPath, err := vfsContext.BuildVfsPath(src)
			if err != nil {
				return fmt.Errorf("building vfs path: %w", err)
			}

			srcFiles, err := srcPath.ReadTree(ctx)
			if err != nil {
				return fmt.Errorf("reading tree: %w", err)
			}
			basePath := srcPath.Path()
			for _, srcFile := range srcFiles {
				b, err := srcFile.ReadFile(ctx)
				if err != nil {
					return fmt.Errorf("reading file: %w", err)
				}

				if !strings.HasPrefix(srcFile.Path(), basePath) {
					return fmt.Errorf("unexpected path: %q", srcFile.Path())
				}
				relativePath := strings.TrimPrefix(srcFile.Path(), basePath)

				bootstrapData.NodeupScriptAdditionalFiles[path.Join(dest, relativePath)] = b
			}

			*pSrc = dest
			return nil

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the wrapped cause to distinguish not-found vs permission vs throttling.
  2. Verify the prefix exists and contains files: `aws s3 ls s3://bucket/prefix/`.
  3. Grant list permission (s3:ListBucket / objectViewer role) to the caller.
  4. Retry with backoff for transient listing errors.

Example fix

// before
srcFiles, err := srcPath.ReadTree(ctx) // fails: s3:ListBucket denied
// after
// IAM: add {"Effect":"Allow","Action":"s3:ListBucket","Resource":"arn:aws:s3:::bucket"}
srcFiles, err := srcPath.ReadTree(ctx)
Defensive patterns

Strategy: retry

Validate before calling

// Ensure the prefix lists successfully before ReadTree
// aws s3 ls s3://bucket/prefix/  (must return objects, not AccessDenied)

Try / catch

if err != nil {
	var notFound *NotFoundError
	if errors.As(err, &notFound) {
		return fmt.Errorf("directory %s missing from state store", src)
	}
	return retry.WithBackoff(func() error { _, err := srcPath.ReadTree(ctx); return err }, 3)
}

Prevention

When it happens

Trigger: BuildVfsPath succeeded on the directory prefix but ReadTree fails: prefix does not exist, caller lacks s3:ListBucket / storage.objects.list permission, or a transient backend error during listing.

Common situations: Directory emptied or renamed in the state store; IAM policy allows GetObject but not ListBucket; throttling during large listings; wrong region endpoint for the bucket.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/2649fc65cbeb5d30. Report an issue: GitHub.