{"record":{"id":"fc6a4ccd1dc67421","repo":"hashicorp/nomad","slug":"block-device-access-type-was-not-requested-but-w","errorCode":null,"errorMessage":"'block-device' access type was not requested but was validated by the controller","messagePattern":"'block-device' access type was not requested but was validated by the controller","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/csi/client.go","lineNumber":589,"sourceCode":"\t\tcapMode := cap.GetAccessMode().GetMode()\n\n\t\t// The plugin may not validate AccessMode, in which case we'll\n\t\t// get UNKNOWN as our response\n\t\tif capMode != csipbv1.VolumeCapability_AccessMode_UNKNOWN {\n\t\t\tif expectedMode != capMode {\n\t\t\t\tmultierror.Append(&err,\n\t\t\t\t\tfmt.Errorf(\"requested access mode %v, got %v\", expectedMode, capMode))\n\t\t\t\tcontinue NEXT_CAP\n\t\t\t}\n\t\t}\n\n\t\tcapBlock := cap.GetBlock()\n\t\tcapMount := cap.GetMount()\n\t\texpectedBlock := expected.GetBlock()\n\t\texpectedMount := expected.GetMount()\n\n\t\tif capBlock != nil && expectedBlock == nil {\n\t\t\tmultierror.Append(&err, fmt.Errorf(\n\t\t\t\t\"'block-device' access type was not requested but was validated by the controller\"))\n\t\t\tcontinue NEXT_CAP\n\t\t}\n\n\t\tif capMount == nil {\n\t\t\tcontinue NEXT_CAP\n\t\t}\n\n\t\tif expectedMount == nil {\n\t\t\tmultierror.Append(&err, fmt.Errorf(\n\t\t\t\t\"'file-system' access type was not requested but was validated by the controller\"))\n\t\t\tcontinue NEXT_CAP\n\t\t}\n\n\t\tif expectedMount.FsType != capMount.FsType {\n\t\t\tmultierror.Append(&err, fmt.Errorf(\n\t\t\t\t\"requested filesystem type %v, got %v\",\n\t\t\t\texpectedMount.FsType, capMount.FsType))","sourceCodeStart":571,"sourceCodeEnd":607,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/plugins/csi/client.go#L571-L607","documentation":"In compareCapabilities, if the controller plugin validated a capability with a 'block' (block-device) access type but the caller never requested block access, Nomad appends this error. It indicates the plugin validated more (or different) capabilities than were requested, so the requested set cannot be considered verified.","triggerScenarios":"ControllerValidateCapabilities receives a request containing only mount-type capabilities, but the plugin's ControllerValidateVolumeCapabilities response includes a capability whose GetBlock() is non-nil, triggering capBlock != nil && expectedBlock == nil.","commonSituations":"A buggy or permissive plugin that blanket-accepts all capabilities regardless of the request; switching a volume from raw block device to filesystem mount without re-registering; plugin version upgrade changing validation behavior.","solutions":["Add an explicit block-device capability to the request if block access is actually intended","If only filesystem access is wanted, file a bug/check the plugin — it should not validate capabilities that were not requested","Upgrade or downgrade the plugin to a version whose validation matches the request","Re-run validation after correcting either the request or the plugin"],"exampleFix":"// before: only mount capability requested, plugin also validates block\nvolume_capabilities = [{ access_type = \"mount\", access_mode = \"single-node-writer\" }]\n// after: either add block or fix plugin; to request block explicitly\nvolume_capabilities = [{ access_type = \"block-device\", access_mode = \"single-node-writer\" }]","handlingStrategy":"validation","validationCode":"// ensure request only contains access types the volume will actually use\nfor _, cap := range req.VolumeCapabilities {\n    if cap.GetBlock() == nil && cap.GetMount() == nil {\n        return errors.New(\"capability must set either mount or block access type\")\n    }\n}\n// if raw block is not intended, do not register block-device capabilities","typeGuard":"func onlyRequestedTypesValidated(expected, validated []*csipbv1.VolumeCapability) error {\n    for _, v := range validated {\n        if v.GetBlock() != nil {\n            found := false\n            for _, e := range expected {\n                if e.GetBlock() != nil { found = true }\n            }\n            if !found { return errors.New(\"block-device validated but not requested\") }\n        }\n    }\n    return nil\n}","tryCatchPattern":"err := client.ControllerValidateCapabilities(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"'block-device' access type was not requested\") {\n        // plugin over-validates: verify plugin version or add block capability\n    }\n    return err\n}","preventionTips":["Only declare access_type = \"block-device\" in the volume spec when raw block is truly used","Keep mount and block capabilities mutually consistent with the volume's usage","Report plugins that validate unrequested capabilities to the vendor; pin a known-good plugin version","Re-validate after any change to the volume's access type"],"tags":["csi","block-device","validation","access-type"],"backgroundTag":"csi-capability-mismatch","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"}