hashicorp/nomad · error
missing NodeID
Error message
missing NodeID
What it means
ControllerPublishVolumeRequest.Validate() rejects requests with an empty NodeID, the node identity the plugin needs to attach the volume to. The provider's attach API requires a target node; an empty NodeID is ambiguous and rejected.
Source
Thrown at plugins/csi/plugin.go:417
return nil
}
return &csipbv1.ControllerPublishVolumeRequest{
VolumeId: r.ExternalID,
NodeId: r.NodeID,
Readonly: r.ReadOnly,
VolumeCapability: r.VolumeCapability.ToCSIRepresentation(),
Secrets: r.Secrets,
VolumeContext: r.VolumeContext,
}
}
func (r *ControllerPublishVolumeRequest) Validate() error {
if r.ExternalID == "" {
return errors.New("missing volume ID")
}
if r.NodeID == "" {
return errors.New("missing NodeID")
}
return nil
}
type ControllerPublishVolumeResponse struct {
PublishContext map[string]string
}
type ControllerUnpublishVolumeRequest struct {
ExternalID string
NodeID string
Secrets structs.CSISecrets
}
func (r *ControllerUnpublishVolumeRequest) ToCSIRepresentation() *csipbv1.ControllerUnpublishVolumeRequest {
if r == nil {
return nil
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Set NodeID to the provider node ID returned by NodeGetInfo (or the plugin's registered node identifier)
- Ensure the node has completed registration/fingerprinting with the plugin before publishing volumes to it
- Check that the caller isn't confusing the CSI node name with the provider instance ID
Example fix
// before
req := &csi.ControllerPublishVolumeRequest{
ExternalID: volumeExternalID,
NodeID: "",
}
// after
nodeInfo, err := nodeClient.NodeGetInfo(ctx, &csi.NodeGetInfoRequest{})
// after
req := &csi.ControllerPublishVolumeRequest{
ExternalID: volumeExternalID,
NodeID: nodeInfo.NodeID,
} Defensive patterns
Strategy: validation
Validate before calling
func validateNodeID(req *csi.ControllerPublishVolumeRequest) error {
if req.NodeID == "" {
return errors.New("NodeID must be the provider node ID from NodeGetInfo")
}
return nil
} Type guard
func hasNodeID(req *csi.ControllerPublishVolumeRequest) bool {
return req != nil && req.NodeID != ""
} Try / catch
if err := req.Validate(); err != nil {
if strings.Contains(err.Error(), "missing NodeID") {
return fmt.Errorf("controller publish refused: fetch NodeID via NodeGetInfo after node registration: %w", err)
}
return err
} Prevention
- Gate volume publishing on completed node registration/fingerprinting
- Store the provider node ID (not hostname) at NodeGetInfo time
- Fail fast if reconciliation reaches publish before the node ID is known
When it happens
Trigger: Calling ControllerPublishVolume with NodeID empty, e.g. the node was never registered with the provider or the caller passed a zero-value request.
Common situations: Node fingerprinting/registration not completed so the provider node ID was never recorded; using the node's hostname instead of the provider-assigned node ID; race where publish starts before NodeRegister finishes.
Related errors
- missing StagingTargetPath
- missing ExternalID
- missing Name
- one of LimitBytes or RequiredBytes must be set if CapacityRa
- CSI.ControllerAttachVolume: VolumeID is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/ce5050d990b81f31.
Report an issue: GitHub.