kubernetes/kops · error

error reading addons file %s: %v

Error message

error reading addons file %s: %v

What it means

The addons List implementation reads a local addons manifest file (under the configured basePath) and failed with an error other than os.IsNotExist, so it cannot return the addons objects. The underlying read error is embedded in the message with the full path.

Source

Thrown at cmd/kops-controller/pkg/controllerclientset/addons.go:64

		cluster:  cluster,
	}

	return r
}

func (c *addonsClient) Replace(addons kubemanifest.ObjectList) error {
	return fmt.Errorf("server-side addons client does not support Addons::Replace")
}

func (c *addonsClient) List(ctx context.Context) (kubemanifest.ObjectList, error) {
	configPath := c.basePath.Join("default")

	b, err := configPath.ReadFile(ctx)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, nil
		}
		return nil, fmt.Errorf("error reading addons file %s: %v", configPath, err)
	}

	objects, err := kubemanifest.LoadObjectsFrom(b)
	if err != nil {
		return nil, err
	}

	return objects, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check file permissions/ownership on the addons file at the printed path
  2. Verify the volume mount providing the addons directory in the kops-controller pod
  3. Confirm the path exists as a regular file, not a directory
  4. If addons are optional, ensure only missing files are tolerated and fix the real I/O error

Example fix

// before
b, err := configPath.ReadFile(ctx)
if err != nil {
	return nil, fmt.Errorf("error reading addons file %s: %v", configPath, err)
}
// after: also tolerate benign errors, log with %w for wrapping
b, err := configPath.ReadFile(ctx)
if err != nil {
	if os.IsNotExist(err) {
		return nil, nil
	}
	return nil, fmt.Errorf("error reading addons file %s: %w", configPath, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check file accessibility before List
if info, err := os.Stat(addonsPath); err == nil && info.IsDir() {
	return fmt.Errorf("addons path %s is a directory", addonsPath)
}

Try / catch

objects, err := addonsClient.List(ctx)
if err != nil {
	if strings.Contains(err.Error(), "error reading addons file") {
		setupLog.Error(err, "addons file unreadable; check mount/permissions")
	}
	return err
}

Prevention

When it happens

Trigger: configPath.ReadFile(ctx) in addonsClient.List fails with a non-notexist error (permission denied, is-a-directory, I/O error); notexist is tolerated and returns nil,nil.

Common situations: Addons file mounted with wrong permissions in the controller pod; basePath pointing at a bad volume mount; file replaced by a directory or unreadable due to read-only/broken mount.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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