hashicorp/nomad · critical · ErrPluginTypeError

CSI Plugin loaded incorrectly

Error message

CSI Plugin loaded incorrectly

What it means

ErrPluginTypeError is returned by CSI.findPlugin when a registered plugin instance does not implement the csi.CSIPlugin interface. It means the object stored/loaded under the plugin ID was created by an incompatible or incorrectly loaded plugin binary, so the client cannot use it as a CSI plugin. Kubernetes-derived check via type assertion pIface.(csi.CSIPlugin) failing.

Source

Thrown at client/csi_endpoint.go:36

	nstructs "github.com/hashicorp/nomad/nomad/structs"
	"github.com/hashicorp/nomad/plugins/csi"
)

// CSI endpoint is used for interacting with CSI plugins on a client.
// TODO: Submit metrics with labels to allow debugging per plugin perf problems.
type CSI struct {
	c *Client
}

const (
	// CSIPluginRequestTimeout is the timeout that should be used when making reqs
	// against CSI Plugins. It is copied from Kubernetes as an initial seed value.
	// https://github.com/kubernetes/kubernetes/blob/e680ad7156f263a6d8129cc0117fda58602e50ad/pkg/volume/csi/csi_plugin.go#L52
	CSIPluginRequestTimeout = 2 * time.Minute
)

var (
	ErrPluginTypeError = errors.New("CSI Plugin loaded incorrectly")
)

// ControllerValidateVolume is used during volume registration to validate
// that a volume exists and that the capabilities it was registered with are
// supported by the CSI Plugin and external volume configuration.
func (c *CSI) ControllerValidateVolume(req *structs.ClientCSIControllerValidateVolumeRequest, resp *structs.ClientCSIControllerValidateVolumeResponse) error {
	defer metrics.MeasureSince([]string{"client", "csi_controller", "validate_volume"}, time.Now())

	if req.VolumeID == "" {
		return errors.New("CSI.ControllerValidateVolume: VolumeID is required")
	}

	if req.PluginID == "" {
		return errors.New("CSI.ControllerValidateVolume: PluginID is required")
	}

	plugin, err := c.findControllerPlugin(req.PluginID)
	if err != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Redeploy/restart the CSI plugin so the correct, compatible binary serves the plugin socket
  2. Verify the plugin implements the CSIPlugin interface (correct gRPC services and version) and matches the expected CSI spec version
  3. Check plugin registration/socket path config to ensure the client is connecting to the intended plugin, not another process
  4. Upgrade host client or plugin so versions are compatible

Example fix

// before (client hits a plugin that doesn't implement CSIPlugin)
plugin, ok := pIface.(csi.CSIPlugin)
if !ok { return nil, ErrPluginTypeError } // "CSI Plugin loaded incorrectly"
// after (redeploy the plugin container image and verify registration)
// e.g. ensure the plugin job runs the CSI v1.x image matching the client's supported version
Defensive patterns

Strategy: try-catch

Validate before calling

plugin, ok := pIface.(csi.CSIPlugin)
if !ok {
    return fmt.Errorf("CSI plugin %q is not a compatible CSIPlugin implementation; redeploy the plugin", pluginID)
}

Type guard

func isCSIPlugin(pIface interface{}) (csi.CSIPlugin, bool) {
    p, ok := pIface.(csi.CSIPlugin)
    return p, ok
}

Try / catch

plugin, err := c.findPlugin(pluginID)
if err != nil {
    if errors.Is(err, ErrPluginTypeError) {
        // plugin binary incompatible/incorrectly loaded: redeploy or check version skew
        return fmt.Errorf("plugin %q loaded incorrectly: %w; redeploy compatible plugin", pluginID, err)
    }
    return err
}

Prevention

When it happens

Trigger: Any CSI client operation (controller/node volume calls) whose lookup path reaches findPlugin and the type assertion at client/csi_endpoint.go:591 fails; plugin registered with a mismatched API version or a binary that does not serve the CSI plugin gRPC surface the client expects.

Common situations: Plugin container image built from an older/newer CSI spec; wrong plugin mounted at the socket so the client talks to a non-CSI plugin; version skew between host client and plugin after upgrade; plugin crashes and a stale/incorrect stub is registered.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/51ec57267fbc085b. Report an issue: GitHub.