hashicorp/nomad · error

missing Capabilities

Error message

missing Capabilities

What it means

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.

Source

Thrown at plugins/csi/client.go:380

		case codes.Internal:
			err = fmt.Errorf("controller plugin returned an internal error, check the plugin allocation logs for more information: %v", err)
		}
		return nil, err
	}

	return &ControllerUnpublishVolumeResponse{}, nil
}

func (c *client) ControllerValidateCapabilities(ctx context.Context, req *ControllerValidateVolumeRequest, opts ...grpc.CallOption) error {
	if err := c.ensureConnected(ctx); err != nil {
		return err
	}
	if req.ExternalID == "" {
		return fmt.Errorf("missing volume ID")
	}

	if req.Capabilities == nil {
		return fmt.Errorf("missing Capabilities")
	}

	creq := req.ToCSIRepresentation()
	resp, err := c.controllerClient.ValidateVolumeCapabilities(ctx, creq, opts...)
	if err != nil {
		code := status.Code(err)
		switch code {
		case codes.NotFound:
			err = fmt.Errorf("volume %q could not be found: %v", req.ExternalID, err)
		case codes.Internal:
			err = fmt.Errorf("controller plugin returned an internal error, check the plugin allocation logs for more information: %v", err)
		}
		return err
	}

	if resp.Message != "" {
		// this should only ever be set if Confirmed isn't set, but
		// it's not a validation failure.

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Populate req.Capabilities with the required VolumeCapability entries (access mode + access type such as mount with fs type) before calling the API.
  2. Fix the volume/task spec so volume_capabilities are declared (e.g. add access_mode and attachment_mode in the Nomad CSI volume block).
  3. Add caller-side validation that Capabilities is non-nil and non-empty before invoking ControllerValidateCapabilities.

Example fix

// before
req := &csi.ControllerValidateVolumeRequest{ExternalID: volID}
err := client.ControllerValidateCapabilities(ctx, req)

// after
req := &csi.ControllerValidateVolumeRequest{
    ExternalID: volID,
    Capabilities: []*csi.VolumeCapability{mustCapability("SINGLE_NODE_WRITER", "mount", "ext4")},
}
err := client.ControllerValidateCapabilities(ctx, req)
Defensive patterns

Strategy: validation

Validate before calling

func validateCapabilities(req *csi.ControllerValidateVolumeRequest) error {
    if len(req.Capabilities) == 0 {
        return fmt.Errorf("ControllerValidateVolumeRequest.Capabilities must contain at least one VolumeCapability")
    }
    return nil
}

Type guard

func hasCapabilities(req *csi.ControllerValidateVolumeRequest) bool {
    return req != nil && req.Capabilities != nil && len(req.Capabilities) > 0
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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


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