hashicorp/nomad · error
CSI.ControllerCreateSnapshot: %v
Error message
CSI.ControllerCreateSnapshot: %v
What it means
CSI.ControllerCreateSnapshot also wraps the error from req.ToCSIRequest() with this message. ToCSIRequest converts the Nomad RPC request into a CSI protobuf request; failure here means the request itself could not be converted, e.g. required fields are missing or invalid before any plugin is contacted.
Source
Thrown at client/csi_endpoint.go:383
return nil
}
func (c *CSI) ControllerCreateSnapshot(req *structs.ClientCSIControllerCreateSnapshotRequest, resp *structs.ClientCSIControllerCreateSnapshotResponse) error {
defer metrics.MeasureSince([]string{"client", "csi_controller", "create_snapshot"}, time.Now())
plugin, err := c.findControllerPlugin(req.PluginID)
if err != nil {
// the server's view of the plugin health is stale, so let it know it
// should retry with another controller instance
return fmt.Errorf("CSI.ControllerCreateSnapshot: %w: %v",
nstructs.ErrCSIClientRPCRetryable, err)
}
defer plugin.Close()
csiReq, err := req.ToCSIRequest()
if err != nil {
return fmt.Errorf("CSI.ControllerCreateSnapshot: %v", err)
}
ctx, cancelFn := c.requestContext()
defer cancelFn()
// CSI ControllerCreateSnapshot errors for timeout, codes.Unavailable and
// codes.ResourceExhausted are retried; all other errors are fatal.
cresp, err := plugin.ControllerCreateSnapshot(ctx, csiReq,
grpc_retry.WithPerRetryTimeout(CSIPluginRequestTimeout),
grpc_retry.WithMax(3),
grpc_retry.WithBackoff(grpc_retry.BackoffExponential(100*time.Millisecond)))
if err != nil {
return fmt.Errorf("CSI.ControllerCreateSnapshot: %v", err)
}
if cresp == nil || cresp.Snapshot == nil {
c.c.logger.Warn("plugin did not return error or snapshot; this is a bug in the plugin and should be reported to the plugin author")
return fmt.Errorf("CSI.ControllerCreateSnapshot: plugin did not return error or snapshot")View on GitHub (pinned to 482b49bf1a)
Solutions
- Check the snapshot request carries a valid source volume ID / secret fields
- Re-run `nomad volume status` to confirm the source volume is registered with complete data
- Align Nomad server and client versions so request schemas match
- Retry the nomad volume snapshot create command with corrected arguments
Example fix
// before nomad volume snapshot create "" my-snap # empty volume ID // after nomad volume snapshot create web-data my-snap
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the source volume is registered and has an external ID before snapshotting:
vol, err := client.Volumes().Get(ctx, "web-data")
if err != nil || vol.ID == "" {
// cannot build a valid CSI CreateSnapshotRequest
return fmt.Errorf("source volume missing: %w", err)
} Try / catch
// Detect the wrapping prefix to distinguish conversion failures
if err := c.ControllerCreateSnapshot(req, resp); err != nil {
var convErr error
if strings.HasPrefix(err.Error(), "CSI.ControllerCreateSnapshot:") {
convErr = err // inspect message for the underlying cause
}
} Prevention
- Run `nomad volume status` to confirm the volume exists before snapshotting
- Keep Nomad server and client versions in sync
- Don't pass empty volume IDs to nomad volume snapshot create
- Validate secrets/parameters against the plugin's documented schema
When it happens
Trigger: req.ToCSIRequest() returns an error while building the CSI CreateSnapshotRequest from the ClientCSIControllerCreateSnapshotRequest, typically because source volume ID or other required fields are empty/invalid.
Common situations: Snapshot requests referencing a volume whose CSI metadata is incomplete; server-side request construction passing an unset SourceVolumeID; older Nomad server talking to newer client (or vice versa) with divergent request schemas.
Related errors
- snapshot cannot be nil
- volume snapshot ID cannot be updated
- missing VolumeID
- missing SnapshotID
- CSI.ControllerCreateSnapshot: %w: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/ae4bac76abb2b771.
Report an issue: GitHub.