hashicorp/nomad · error
validation: %s
Error message
validation: %s
What it means
This aggregates all field-validation failures found while validating a CSIVolume struct into a single error prefixed with 'validation: '. It is thrown when user-defined volume fields violate constraints — here, topology requests whose Segments field is empty — or any of the other checks in the same function (empty RequestedCapabilities, invalid AccessMode/Capability pairs, bad MountFlags, etc.).
Source
Thrown at nomad/structs/csi.go:771
errs = append(errs, "only one of snapshot_id and clone_id is allowed")
}
if len(v.RequestedCapabilities) == 0 {
errs = append(errs, "must include at least one capability block")
}
if v.RequestedTopologies != nil {
for _, t := range v.RequestedTopologies.Required {
if t != nil && len(t.Segments) == 0 {
errs = append(errs, "required topology is missing segments field")
}
}
for _, t := range v.RequestedTopologies.Preferred {
if t != nil && len(t.Segments) == 0 {
errs = append(errs, "preferred topology is missing segments field")
}
}
}
if len(errs) > 0 {
return fmt.Errorf("validation: %s", strings.Join(errs, ", "))
}
return nil
}
// Merge updates the mutable fields of a volume with those from
// another volume. CSIVolume has many user-defined fields which are
// immutable once set, and many fields that are not
// user-settable. Merge will return an error if we try to mutate the
// user-defined immutable fields after they're set, but silently
// ignore fields that are controlled by Nomad.
func (v *CSIVolume) Merge(other *CSIVolume) error {
if other == nil {
return nil
}
var errs *multierror.Error
if v.Name != other.Name && other.Name != "" {View on GitHub (pinned to 482b49bf1a)
Solutions
- Read the joined message after 'validation: ' — it lists every offending field; fix each listed field in the volume spec.
- Provide non-empty segments in every requested/preferred topology, e.g. topology_request { segments { rack = "r1" } }.
- Ensure each requested_capability sets BOTH access_mode and attachment_mode and that they are compatible with the volume's declared access mode.
- Validate the spec locally before registering (nomad volume validate or a dry run) to catch all errs at once.
Example fix
// before
topology_request {
segments {} # empty -> "preferred topology is missing segments field"
}
// after
topology_request {
segments {
rack = "rack-1"
zone = "us-east-1a"
}
} Defensive patterns
Strategy: validation
Validate before calling
func validateVolumeSpec(vol *api.CSIVolume) error {
var errs []string
for _, t := range append(vol.RequestedTopologies, vol.PreferredTopology) {
if t != nil && len(t.Segments) == 0 {
errs = append(errs, "topology missing segments")
}
}
for _, c := range vol.RequestedCapabilities {
if c.AccessMode == "" || c.AttachmentMode == "" {
errs = append(errs, "capability needs both access_mode and attachment_mode")
}
}
if len(errs) > 0 {
return fmt.Errorf("validation: %s", strings.Join(errs, ", "))
}
return nil
}
// run before nomad volume register Type guard
func topologyHasSegments(t *structs.CSITopology) bool {
return t == nil || len(t.Segments) > 0
} Try / catch
err := vol.Validate()
if err != nil {
var verr *fmt.wrapError
if strings.HasPrefix(err.Error(), "validation: ") {
for _, problem := range strings.Split(strings.TrimPrefix(err.Error(), "validation: "), ", ") {
log.Printf("volume spec problem: %s", problem)
}
return err // fix the spec; retrying will not help
}
return err
} Prevention
- Every topology block in the volume spec must define at least one segment key/value.
- Every requested_capability must set both access_mode and attachment_mode.
- Run nomad volume validate (or the job validation endpoint) before registering.
- Re-validate existing specs after upgrading Nomad, since validation rules can tighten.
When it happens
Trigger: Calling CSIVolume.Validate (via nomad volume register / job volume validation RPC) when: requested topologies or preferred topologies have empty Segments; a capability has AccessMode but no AttachmentMode (or vice versa); requested capabilities conflict with the volume's declared AccessMode; mount flags set on non-filesystem volumes.
Common situations: Registering a volume with 'topology_request: {segments: {}}' in an HCL/JSON volume spec; copy-pasting a volume spec with capability blocks missing attachment_mode; operator tightening validation in a newer Nomad version so previously-registered specs now fail.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- missing secret ID
- CSI.ControllerAttachVolume: VolumeID is required
- CSI.ControllerAttachVolume: ClientCSINodeID is required
- CSI.ControllerDetachVolume: VolumeID is required
- CSI.ControllerDetachVolume: ClientCSINodeID is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/1dfa48414c37da63.
Report an issue: GitHub.