{"record":{"id":"7250206654672dd3","repo":"hashicorp/nomad","slug":"missing-capabilities","errorCode":null,"errorMessage":"missing Capabilities","messagePattern":"missing Capabilities","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/csi/client.go","lineNumber":380,"sourceCode":"\t\tcase codes.Internal:\n\t\t\terr = fmt.Errorf(\"controller plugin returned an internal error, check the plugin allocation logs for more information: %v\", err)\n\t\t}\n\t\treturn nil, err\n\t}\n\n\treturn &ControllerUnpublishVolumeResponse{}, nil\n}\n\nfunc (c *client) ControllerValidateCapabilities(ctx context.Context, req *ControllerValidateVolumeRequest, opts ...grpc.CallOption) error {\n\tif err := c.ensureConnected(ctx); err != nil {\n\t\treturn err\n\t}\n\tif req.ExternalID == \"\" {\n\t\treturn fmt.Errorf(\"missing volume ID\")\n\t}\n\n\tif req.Capabilities == nil {\n\t\treturn fmt.Errorf(\"missing Capabilities\")\n\t}\n\n\tcreq := req.ToCSIRepresentation()\n\tresp, err := c.controllerClient.ValidateVolumeCapabilities(ctx, creq, opts...)\n\tif err != nil {\n\t\tcode := status.Code(err)\n\t\tswitch code {\n\t\tcase codes.NotFound:\n\t\t\terr = fmt.Errorf(\"volume %q could not be found: %v\", req.ExternalID, err)\n\t\tcase codes.Internal:\n\t\t\terr = fmt.Errorf(\"controller plugin returned an internal error, check the plugin allocation logs for more information: %v\", err)\n\t\t}\n\t\treturn err\n\t}\n\n\tif resp.Message != \"\" {\n\t\t// this should only ever be set if Confirmed isn't set, but\n\t\t// it's not a validation failure.","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/plugins/csi/client.go#L362-L398","documentation":"This error is returned by ControllerValidateCapabilities when the request's Capabilities field is nil. Validation of volume capabilities is meaningless without the capabilities to check, so the client fails fast before issuing the gRPC ValidateVolumeCapabilities call to the CSI plugin. Like the volume ID check, it guards against sending structurally incomplete requests.","triggerScenarios":"Calling ControllerValidateCapabilities with a *ControllerValidateVolumeRequest whose Capabilities pointer is nil — e.g. the request was constructed with zero-value struct literals, or the capability list was lost during deserialization/config parsing.","commonSituations":"A Nomad task group's volume_capabilities block is empty or missing so the parsed capabilities are nil; a volume spec YAML/HCL omitted the capability block; code paths that build the request programmatically forgot to attach CSI capability structs; an upgrade changed the capability struct shape and old callers pass nil.","solutions":["Populate req.Capabilities with the required VolumeCapability entries (access mode + access type such as mount with fs type) before calling the API.","Fix the volume/task spec so volume_capabilities are declared (e.g. add access_mode and attachment_mode in the Nomad CSI volume block).","Add caller-side validation that Capabilities is non-nil and non-empty before invoking ControllerValidateCapabilities."],"exampleFix":"// before\nreq := &csi.ControllerValidateVolumeRequest{ExternalID: volID}\nerr := client.ControllerValidateCapabilities(ctx, req)\n\n// after\nreq := &csi.ControllerValidateVolumeRequest{\n    ExternalID: volID,\n    Capabilities: []*csi.VolumeCapability{mustCapability(\"SINGLE_NODE_WRITER\", \"mount\", \"ext4\")},\n}\nerr := client.ControllerValidateCapabilities(ctx, req)","handlingStrategy":"validation","validationCode":"func validateCapabilities(req *csi.ControllerValidateVolumeRequest) error {\n    if len(req.Capabilities) == 0 {\n        return fmt.Errorf(\"ControllerValidateVolumeRequest.Capabilities must contain at least one VolumeCapability\")\n    }\n    return nil\n}","typeGuard":"func hasCapabilities(req *csi.ControllerValidateVolumeRequest) bool {\n    return req != nil && req.Capabilities != nil && len(req.Capabilities) > 0\n}","tryCatchPattern":null,"preventionTips":["Build requests through a constructor/helper that requires capabilities rather than populating struct fields ad hoc.","Ensure Nomad volume and task-group specs declare access_mode and attachment_mode blocks.","Surface capability configuration errors at spec-parse time instead of at RPC time."],"tags":["csi","validation","nil-pointer","storage"],"backgroundTag":"missing-required-argument","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}