{"record":{"id":"1dfa48414c37da63","repo":"hashicorp/nomad","slug":"validation-s","errorCode":null,"errorMessage":"validation: %s","messagePattern":"validation: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/csi.go","lineNumber":771,"sourceCode":"\t\terrs = append(errs, \"only one of snapshot_id and clone_id is allowed\")\n\t}\n\tif len(v.RequestedCapabilities) == 0 {\n\t\terrs = append(errs, \"must include at least one capability block\")\n\t}\n\tif v.RequestedTopologies != nil {\n\t\tfor _, t := range v.RequestedTopologies.Required {\n\t\t\tif t != nil && len(t.Segments) == 0 {\n\t\t\t\terrs = append(errs, \"required topology is missing segments field\")\n\t\t\t}\n\t\t}\n\t\tfor _, t := range v.RequestedTopologies.Preferred {\n\t\t\tif t != nil && len(t.Segments) == 0 {\n\t\t\t\terrs = append(errs, \"preferred topology is missing segments field\")\n\t\t\t}\n\t\t}\n\t}\n\tif len(errs) > 0 {\n\t\treturn fmt.Errorf(\"validation: %s\", strings.Join(errs, \", \"))\n\t}\n\treturn nil\n}\n\n// Merge updates the mutable fields of a volume with those from\n// another volume. CSIVolume has many user-defined fields which are\n// immutable once set, and many fields that are not\n// user-settable. Merge will return an error if we try to mutate the\n// user-defined immutable fields after they're set, but silently\n// ignore fields that are controlled by Nomad.\nfunc (v *CSIVolume) Merge(other *CSIVolume) error {\n\tif other == nil {\n\t\treturn nil\n\t}\n\n\tvar errs *multierror.Error\n\n\tif v.Name != other.Name && other.Name != \"\" {","sourceCodeStart":753,"sourceCodeEnd":789,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/csi.go#L753-L789","documentation":"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.).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ntopology_request {\n  segments {} # empty -> \"preferred topology is missing segments field\"\n}\n// after\ntopology_request {\n  segments {\n    rack = \"rack-1\"\n    zone = \"us-east-1a\"\n  }\n}","handlingStrategy":"validation","validationCode":"func validateVolumeSpec(vol *api.CSIVolume) error {\n    var errs []string\n    for _, t := range append(vol.RequestedTopologies, vol.PreferredTopology) {\n        if t != nil && len(t.Segments) == 0 {\n            errs = append(errs, \"topology missing segments\")\n        }\n    }\n    for _, c := range vol.RequestedCapabilities {\n        if c.AccessMode == \"\" || c.AttachmentMode == \"\" {\n            errs = append(errs, \"capability needs both access_mode and attachment_mode\")\n        }\n    }\n    if len(errs) > 0 {\n        return fmt.Errorf(\"validation: %s\", strings.Join(errs, \", \"))\n    }\n    return nil\n}\n// run before nomad volume register","typeGuard":"func topologyHasSegments(t *structs.CSITopology) bool {\n    return t == nil || len(t.Segments) > 0\n}","tryCatchPattern":"err := vol.Validate()\nif err != nil {\n    var verr *fmt.wrapError\n    if strings.HasPrefix(err.Error(), \"validation: \") {\n        for _, problem := range strings.Split(strings.TrimPrefix(err.Error(), \"validation: \"), \", \") {\n            log.Printf(\"volume spec problem: %s\", problem)\n        }\n        return err // fix the spec; retrying will not help\n    }\n    return err\n}","preventionTips":["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."],"tags":["nomad","csi","validation","volume-spec"],"backgroundTag":"schema-validation-failed","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"}