hashicorp/nomad · error

CSI.ControllerCreateSnapshot: plugin did not return error or

Error message

CSI.ControllerCreateSnapshot: plugin did not return error or snapshot

What it means

After a successful (err == nil) ControllerCreateSnapshot call, the CSI spec still requires a Snapshot object in the response. If cresp is nil or cresp.Snapshot is nil, the plugin returned success with no data. Nomad explicitly logs that this is a bug in the plugin and returns this error rather than a nil-pointer panic.

Source

Thrown at client/csi_endpoint.go:401

		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")
	}
	resp.ID = cresp.Snapshot.ID
	resp.ExternalSourceVolumeID = cresp.Snapshot.SourceVolumeID
	resp.SizeBytes = cresp.Snapshot.SizeBytes
	resp.CreateTime = cresp.Snapshot.CreateTime
	resp.IsReady = cresp.Snapshot.IsReady

	return nil
}

func (c *CSI) ControllerDeleteSnapshot(req *structs.ClientCSIControllerDeleteSnapshotRequest, resp *structs.ClientCSIControllerDeleteSnapshotResponse) error {
	defer metrics.MeasureSince([]string{"client", "csi_controller", "delete_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.ControllerDeleteSnapshot: %w: %v",

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Report the bug to the plugin author, as the log line instructs
  2. Upgrade/downgrade the CSI plugin to a version with correct CreateSnapshot responses
  3. Check whether the snapshot actually exists in the backend before retrying, to avoid duplicates
  4. Recreate the snapshot after fixing/replacing the plugin

Example fix

// before (plugin side)
return &csi.CreateSnapshotResponse{}, nil
// after
return &csi.CreateSnapshotResponse{Snapshot: &csi.Snapshot{
    SnapshotId: id, SourceVolumeId: volID, ReadyToUse: true,
}}, nil
Defensive patterns

Strategy: validation

Validate before calling

// Before retrying, check whether the snapshot was actually created in the backend
// (via cloud console/API or `nomad volume snapshot list`) to avoid duplicate snapshots.
snaps := listSnapshotsFromBackend()
if !contains(snaps, snapshotID) { /* safe to retry create */ }

Try / catch

// Treat this as a plugin bug, not transient
if err := c.ControllerCreateSnapshot(req, resp); err != nil {
    if strings.Contains(err.Error(), "plugin did not return error or snapshot") {
        // verify backend state, then report to plugin vendor
    }
}

Prevention

When it happens

Trigger: Plugin responds to CreateSnapshot with an empty or snapshot-less response despite returning a gRPC OK status — a plugin contract violation.

Common situations: Vendor plugin bugs where the snapshot was created but the response object was never populated; plugins handling async snapshot creation incorrectly (returning before filling Snapshot); plugin version regressions.

Related errors


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