ahmetb/kubectx · error

failed to truncate file: %w

Error message

failed to truncate file: %w

What it means

kubeconfigFile.Reset empties the underlying os.File via Truncate(0) so Save can rewrite it in place. This error wraps any Truncate failure with the original *os.PathError in %w, meaning the file could not be resized before rewriting.

Source

Thrown at internal/kubeconfig/kubeconfigloader.go:65

		f, err := os.OpenFile(p, os.O_RDWR, 0)
		if err != nil {
			if os.IsNotExist(err) {
				continue
			}
			return nil, fmt.Errorf("failed to open file %q: %w", p, err)
		}
		files = append(files, &kubeconfigFile{File: f, path: p})
	}
	if len(files) == 0 {
		return nil, fmt.Errorf("kubeconfig file not found: %w",
			&os.PathError{Op: "open", Path: paths[0], Err: os.ErrNotExist})
	}
	return files, nil
}

func (kf *kubeconfigFile) Reset() error {
	if err := kf.Truncate(0); err != nil {
		return fmt.Errorf("failed to truncate file: %w", err)
	}
	if _, err := kf.Seek(0, 0); err != nil {
		return fmt.Errorf("failed to seek in file: %w", err)
	}
	return nil
}

func kubeconfigPaths() ([]string, error) {
	// KUBECONFIG env var
	if v := os.Getenv("KUBECONFIG"); v != "" {
		return filepath.SplitList(v), nil
	}

	// default path
	home := cmdutil.HomeDir()
	if home == "" {
		return nil, errors.New("HOME or USERPROFILE environment variable not set")
	}

View on GitHub (pinned to 12ad6fb22e)

Solutions

  1. Inspect the wrapped *os.PathError for the errno and fix the filesystem condition (space, read-only flag)
  2. Ensure the file was opened O_RDWR (the standard loader does this) and not closed elsewhere before Reset
  3. Check permissions on the file and directory for the current user
  4. Retry after the transient mount/disk condition is resolved

Example fix

// before
f, _ := os.Open(p)          // read-only handle
loader.Reset()              // truncate fails
// after
f, _ := os.OpenFile(p, os.O_RDWR, 0)
loader.Reset()
Defensive patterns

Strategy: try-catch

Validate before calling

// Go
// Ensure writable and not on a read-only mount before mutating
if fi, err := os.Stat(p); err != nil || fi.Mode().Perm()&0200 == 0 {
    return fmt.Errorf("cannot reset %s: not writable", p)
}

Type guard

func isReadOnlyFSErr(err error) bool {
    return errors.Is(err, syscall.EROFS) || errors.Is(err, os.ErrPermission)
}

Try / catch

if err := kf.Reset(); err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) && errors.Is(pe.Err, os.ErrPermission) {
        return fmt.Errorf("kubeconfig %s is not writable (chmod needed): %w", pe.Path, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Reset when the file cannot be truncated: the file was opened read-only, the filesystem is read-only, the file descriptor is already closed, or the OS returns EIO/EACCES on ftruncate.

Common situations: Filesystem remounted read-only after Load opened the file (disk-full failover); another component closed the shared *os.File first; editing a kubeconfig on a mounted CD/ISO or read-only volume.

Related errors


AI-assisted analysis of ahmetb/kubectx@12ad6fb22e (2026-09-02). Data as JSON: /api/errors/33262ceff08c5f81. Report an issue: GitHub.