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
- Redeploy/restart the CSI plugin so the correct, compatible binary serves the plugin socket
- Verify the plugin implements the CSIPlugin interface (correct gRPC services and version) and matches the expected CSI spec version
- Check plugin registration/socket path config to ensure the client is connecting to the intended plugin, not another process
- 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
- Pin the plugin container image to a CSI spec version compatible with the host client
- Verify the plugin gRPC socket serves the expected CSI services after deploy
- Watch for plugin job crashes/restarts that can leave a stale registration
- Test controller/node volume operations after every client or plugin upgrade
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
- CSI.ControllerListVolumes: plugin returned an invalid entry
- CSI.NodeDetachVolume: %v
- controller attach volume: %v
- controller validate volume: %v
- controller detach volume: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/51ec57267fbc085b.
Report an issue: GitHub.