kubernetes/kops · error

error getting relative path for %s

Error message

error getting relative path for %s

What it means

For each file read, loadFrom computes its path relative to the template base directory via vfs.RelativePath to derive the template key. If RelativePath fails (the file is not actually under the base path), the layout is inconsistent and loading aborts with this error.

Source

Thrown at pkg/templates/templates.go:74

func (t *Templates) loadFrom(ctx context.Context, base vfs.Path) error {
	files, err := base.ReadTree(ctx)
	if err != nil {
		return fmt.Errorf("error reading from %s", base)
	}

	for _, f := range files {
		contents, err := f.ReadFile(ctx)
		if err != nil {
			if os.IsNotExist(err) {
				// This is just an annoyance of gobindata - we can't tell the difference between files & directories.  Ignore.
				continue
			}
			return fmt.Errorf("error reading %s: %v", f, err)
		}

		key, err := vfs.RelativePath(base, f)
		if err != nil {
			return fmt.Errorf("error getting relative path for %s", f)
		}

		isTemplate := strings.HasSuffix(key, ".template")
		key = strings.TrimSuffix(key, ".template")
		klog.V(6).Infof("loading resource %q", key)
		t.resources[key] = fi.NewBytesResource(contents)
		t.isTemplate[key] = isTemplate
	}
	return nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Ensure the template base directory is a plain directory containing the templates directly (no symlinks escaping it)
  2. Use a single consistent VFS backend for base and its contents
  3. Check for duplicate/overlapping --model or path configuration
  4. If it persists, inspect vfs.RelativePath's inputs by logging base and f at higher verbosity

Example fix

// before
ln -s /home/me/extra-templates ~/.kops/models/mymodel/extra  # escapes base
// after
cp -rL /home/me/extra-templates ~/.kops/models/mymodel/extra # copy contents inside base
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the file lives under base before adding it
rel, err := vfs.RelativePath(base, f)
if err != nil {
	klog.Warningf("skipping %s: not under %s", f, base)
}

Type guard

func isUnderBase(base, f vfs.Path) bool {
	_, err := vfs.RelativePath(base, f)
	return err == nil
}

Prevention

When it happens

Trigger: vfs.RelativePath(base, f) returns an error because the VFS entry f cannot be expressed as a child of the base path — e.g. mixed VFS backends, symlinks escaping the base, or an unusual path construction.

Common situations: Mounting/overlapping VFS paths (a base directory that is an ancestor/sibling mismatch), custom model directories with symlinks pointing outside the base, or backend-specific path quirks in S3/GCS prefixes.

Related errors


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