hashicorp/nomad · error

requested access mode %v, got %v

Error message

requested access mode %v, got %v

What it means

During ControllerValidateCapabilities, Nomad compares each requested VolumeCapability against the capabilities the controller plugin says it validated. If the plugin reports a validated access mode different from the one requested (and not UNKNOWN), Nomad records 'requested access mode %v, got %v' into the returned multierror.

Source

Thrown at plugins/csi/client.go:578

// expect have been validated, only that the ones that have been validated
// match. This appears to violate the CSI specification but until that's been
// resolved in upstream we have to loosen our validation requirements. The
// tradeoff is that we're more likely to have runtime errors during
// NodeStageVolume.
func compareCapabilities(expected *csipbv1.VolumeCapability, got []*csipbv1.VolumeCapability) error {
	var err multierror.Error
NEXT_CAP:
	for _, cap := range got {

		expectedMode := expected.GetAccessMode().GetMode()
		capMode := cap.GetAccessMode().GetMode()

		// The plugin may not validate AccessMode, in which case we'll
		// get UNKNOWN as our response
		if capMode != csipbv1.VolumeCapability_AccessMode_UNKNOWN {
			if expectedMode != capMode {
				multierror.Append(&err,
					fmt.Errorf("requested access mode %v, got %v", expectedMode, capMode))
				continue NEXT_CAP
			}
		}

		capBlock := cap.GetBlock()
		capMount := cap.GetMount()
		expectedBlock := expected.GetBlock()
		expectedMount := expected.GetMount()

		if capBlock != nil && expectedBlock == nil {
			multierror.Append(&err, fmt.Errorf(
				"'block-device' access type was not requested but was validated by the controller"))
			continue NEXT_CAP
		}

		if capMount == nil {
			continue NEXT_CAP
		}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Align the job's volume capability access_mode with what the plugin actually supports (check the driver docs / ControllerGetCapabilities)
  2. Inspect the full multierror output to see which capability mismatched and update the volume specification
  3. Downgrade to an access mode the plugin validates, e.g. single-node-writer for RWO filesystems
  4. Re-run ControllerValidateCapabilities after fixing to confirm all capabilities pass

Example fix

// before (job volume stanza)
capability { access_mode = "multi-node-multi-writer"  access_type = "mount" }
// after
capability { access_mode = "single-node-writer"  access_type = "mount" }
Defensive patterns

Strategy: validation

Validate before calling

// validate access modes against plugin capabilities before submitting
sup := map[csipbv1.VolumeCapability_AccessMode_Mode]bool{}
caps, _ := plugin.ControllerGetCapabilities(ctx, &csi.ControllerGetCapabilitiesRequest{})
// ...collect supported access modes from plugin/volume capabilities...
for _, cap := range req.VolumeCapabilities {
    if !sup[cap.GetAccessMode().GetMode()] {
        return fmt.Errorf("access mode %v not supported by plugin", cap.GetAccessMode().GetMode())
    }
}

Type guard

func accessModesMatch(expected, validated *csipbv1.VolumeCapability) bool {
    cm := validated.GetAccessMode().GetMode()
    return cm == csipbv1.VolumeCapability_AccessMode_UNKNOWN ||
        expected.GetAccessMode().GetMode() == cm
}

Try / catch

err := client.ControllerValidateCapabilities(ctx, req)
if err != nil {
    if merr, ok := err.(*multierror.Error); ok {
        for _, e := range merr.Errors {
            if strings.Contains(e.Error(), "requested access mode") {
                // fix the volume spec's access_mode and re-validate
            }
        }
    }
    return err
}

Prevention

When it happens

Trigger: Calling ControllerValidateCapabilities with a VolumeCapability whose AccessMode (e.g. MULTI_NODE_READER_ONLY) differs from the access mode the plugin validated and echoed back (e.g. SINGLE_NODE_WRITER), for capabilities other than the single-node-writer exception path.

Common situations: Job volume stanza declares access_mode = "multi-node-multi-writer" but the storage driver only supports single-node-writer; a plugin version change altered which access mode it reports validating; copying a volume block from another job with a different access mode; typo in HCL access_mode value.

Related errors


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