kubernetes/kops · error

unexpected path: %q

Error message

unexpected path: %q

What it means

While remapping a remote s3:// tree to a local host directory, kops asserts that every file returned by ReadTree lives under the tree's base path (basePath := srcPath.Path()); relative paths are computed with strings.TrimPrefix. If a listed file's path does not have that prefix, the invariant is broken and this error is thrown instead of writing the file to a bogus local location.

Source

Thrown at pkg/commands/toolbox_enroll.go:916

			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
		}

		for i := range nodeupConfig.EtcdManifests {
			if err := remapFile(&nodeupConfig.EtcdManifests[i], path.Join(targetDir)); err != nil {
				return nil, err
			}
		}

		// The kops-channels static pod is built at cloudup with the remote bootstrap URL baked
		// into its args. To run on an enrolled node without state-store credentials, copy the

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Report/capture the offending path printed in the error (%q) and compare it with the ConfigStore.Base value to see how it diverges (trailing slash, case, relative form).
  2. Upgrade (or downgrade) kops to a version where vfs.ReadTree path handling matches your backend; check the vfs S3/GCS implementation for known normalization fixes.
  3. Sanity-check the state store keys (aws s3 ls) for odd characters, leading slashes, or mixed-case segments under the base prefix and normalize them.
  4. If only one backend is affected, switch the state store to a standard layout (e.g. plain s3://bucket/cluster) and re-run enroll.

Example fix

// before: keys uploaded with leading slash break prefix matching
aws s3 cp addons/ s3://bucket//cluster/addons/ --recursive
// after: upload under the exact base path with no double slashes
aws s3 cp addons/ s3://bucket/cluster/addons/ --recursive
Defensive patterns

Strategy: validation

Validate before calling

// Before enroll: confirm state-store keys sit under the base prefix with no oddities
aws s3 ls s3://<bucket>/<cluster>/addons/ --recursive | awk '{print $4}' | \
  grep -v '^<cluster>/addons/' && echo 'WARNING: keys outside expected base prefix'

Type guard

func hasBasePrefix(p, basePath string) bool {
    return strings.HasPrefix(p, basePath)
}

Try / catch

if err := runToolboxEnroll(ctx, ...); err != nil {
    var unexpected *ErrUnexpectedPath // or match on "unexpected path:"
    if strings.Contains(err.Error(), "unexpected path:") {
        log.Fatalf("vfs tree layout invariant broken; inspect the path in: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: GetBootstrapData -> remapTree on an s3:// addons/keypairs/secrets tree where the vfs VFSPath enumeration yields a path that does not share the srcPath base prefix — typically a backend change/bug in vfs ReadTree path normalization, an unexpected symlink-like or case-differing key, or the tree path being mutated between BuildVfsPath and iteration.

Common situations: Using an unusual or customized state-store backend whose object keys don't normalize the same way as vfs's base path; version drift where ReadTree starts returning relative or absolute-normalized keys; running a patched/newer kops against a state store layout the code doesn't expect.

Related errors


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