kubernetes/kops · error

error reading '%s' on config drive: %v

Error message

error reading '%s' on config drive: %v

What it means

Once the config drive is mounted, getFromConfigDrive (upup/pkg/fi/cloudup/openstack/openstackmetadata/metadata.go:128) opens the metadata JSON file at mds.configDrivePath inside the mount. If os.Open fails (file missing, wrong path, unreadable filesystem), this error naming the path is returned.

Source

Thrown at upup/pkg/fi/cloudup/openstack/openstackmetadata/metadata.go:128

		if err != nil {
			return nil, fmt.Errorf("unable to run blkid: %v", err)
		}
		dev = strings.TrimSpace(string(out))
	}

	err := mds.mounter.Mount(dev, mds.mountTarget, "iso9660", []string{"ro"})
	if err != nil {
		err = mds.mounter.Mount(dev, mds.mountTarget, "vfat", []string{"ro"})
	}
	if err != nil {
		return nil, fmt.Errorf("error mounting configdrive '%s': %v", dev, err)
	}
	defer mds.mounter.Unmount(mds.mountTarget)

	f, err := os.Open(
		path.Join(mds.mountTarget, mds.configDrivePath))
	if err != nil {
		return nil, fmt.Errorf("error reading '%s' on config drive: %v", mds.configDrivePath, err)
	}
	defer f.Close()

	return mds.parseMetadata(f)
}

// getFromMetadataService tries to get metadata from a metadata service endpoint and returns it as InstanceMetadata.
// If the service endpoint cannot be contacted or reports a different status than StatusOK it will return an error.
func (mds MetadataService) getFromMetadataService() (*InstanceMetadata, error) {
	var client http.Client

	resp, err := client.Get(mds.serviceURL)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusOK {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify the expected file exists on the mounted drive: `ls <mountTarget>/<configDrivePath>`; adjust configDrivePath if your cloud lays files out differently.
  2. Regenerate the instance with a standard config drive (nova boot --config-drive true).
  3. Check the config-drive image integrity (e.g. `isoinfo -l -i <dev>`) and that the correct device was mounted.
  4. Confirm file permissions allow the reading user (root) to open the file.

Example fix

// before
f, err := os.Open(path.Join(mds.mountTarget, mds.configDrivePath))
if err != nil {
    return nil, fmt.Errorf("error reading '%s' on config drive: %v", mds.configDrivePath, err)
}
// after — check the file exists first for a clearer diagnosis
metaPath := path.Join(mds.mountTarget, mds.configDrivePath)
if _, err := os.Stat(metaPath); os.IsNotExist(err) {
    return nil, fmt.Errorf("config drive mounted but %s is missing; wrong drive or layout", metaPath)
}
f, err := os.Open(metaPath)
Defensive patterns

Strategy: validation

Validate before calling

// After mounting, verify the expected metadata file exists before opening it
metaPath := filepath.Join("/mnt/config-drive", "openstack/latest/meta_data.json")
if fi, err := os.Stat(metaPath); err != nil || fi.IsDir() {
    return fmt.Errorf("expected metadata file %s not present on config drive", metaPath)
}

Try / catch

meta, err := mds.getFromConfigDrive()
if err != nil {
    var pathErr *fs.PathError
    if errors.As(err, &pathErr) && strings.Contains(err.Error(), "on config drive") {
        // wrong layout or wrong device — fall back to the metadata service
        return mds.getFromMetadataService()
    }
    return nil, err
}

Prevention

When it happens

Trigger: os.Open(path.Join(mds.mountTarget, mds.configDrivePath)) fails — the expected file (e.g. openstack/latest/meta_data.json) is absent from the config drive, the drive content layout differs from the expected path, or the mount succeeded but the filesystem is unreadable/corrupt.

Common situations: Config drive produced by a tool that lays out files differently than the expected configDrivePath; truncated or corrupted config-drive image; mounting the wrong device as the config drive; permission problems on the mounted filesystem.

Related errors


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