hashicorp/nomad · error
missing SnapshotID
Error message
missing SnapshotID
What it means
This error is returned by ControllerDeleteSnapshotRequest.Validate when SnapshotID is empty. Deleting a snapshot requires the provider-assigned snapshot ID to identify which snapshot to remove; an empty ID is treated as a malformed request and rejected locally before the ControllerDeleteSnapshot gRPC call.
Source
Thrown at plugins/csi/plugin.go:808
CreateTime int64
IsReady bool
}
type ControllerDeleteSnapshotRequest struct {
SnapshotID string
Secrets structs.CSISecrets
}
func (r *ControllerDeleteSnapshotRequest) ToCSIRepresentation() *csipbv1.DeleteSnapshotRequest {
return &csipbv1.DeleteSnapshotRequest{
SnapshotId: r.SnapshotID,
Secrets: r.Secrets,
}
}
func (r *ControllerDeleteSnapshotRequest) Validate() error {
if r.SnapshotID == "" {
return errors.New("missing SnapshotID")
}
return nil
}
type ControllerListSnapshotsRequest struct {
MaxEntries int32
StartingToken string
Secrets structs.CSISecrets
}
func (r *ControllerListSnapshotsRequest) ToCSIRepresentation() *csipbv1.ListSnapshotsRequest {
return &csipbv1.ListSnapshotsRequest{
MaxEntries: r.MaxEntries,
StartingToken: r.StartingToken,
Secrets: r.Secrets,
}
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Populate SnapshotID with the provider-assigned ID from ControllerCreateSnapshotResponse before deleting.
- Skip records with empty snapshot IDs in cleanup loops instead of passing them through.
- Look up the snapshot ID via a list-snapshots call (e.g. by Name) if only the name is known.
- Fix upstream creation failures that leave snapshot records without IDs.
Example fix
// before
for _, s := range snaps {
client.DeleteSnapshot(&ControllerDeleteSnapshotRequest{SnapshotID: s.ID}) // may be ""
}
// after
for _, s := range snaps {
if s.ID == "" { continue }
client.DeleteSnapshot(&ControllerDeleteSnapshotRequest{SnapshotID: s.ID})
} Defensive patterns
Strategy: validation
Validate before calling
if req.SnapshotID == "" {
return fmt.Errorf("cannot delete snapshot: snapshot ID is required")
} Type guard
func deletableSnapshot(r *ControllerDeleteSnapshotRequest) bool {
return r != nil && r.SnapshotID != ""
} Prevention
- Skip snapshot records with empty IDs in retention/cleanup loops.
- Keep the ID returned by ControllerCreateSnapshotResponse alongside the name.
- Resolve names to IDs via a list-snapshots call before deleting by name.
When it happens
Trigger: Calling the delete-snapshot path with ControllerDeleteSnapshotRequest{SnapshotID: ""} — e.g. cleanup automation operating on a snapshot record whose creation failed and thus never received an ID, or a zero-value request struct.
Common situations: Retention jobs iterating over snapshot lists where one entry has an empty ID (failed creation); deleting by snapshot name instead of ID and passing the empty lookup result; env-var interpolation leaving the ID blank.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- missing VolumeID
- missing ExternalVolumeID
- one of LimitBytes or RequiredBytes must be set
- CSI.ControllerAttachVolume: VolumeID is required
- CSI.ControllerAttachVolume: ClientCSINodeID is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/9c9c9afdb2e7b0cc.
Report an issue: GitHub.