{"record":{"id":"0fb34bc09f495cb6","repo":"hashicorp/nomad","slug":"missing-secret-id","errorCode":null,"errorMessage":"missing secret ID","messagePattern":"missing secret ID","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"api/acl.go","lineNumber":150,"sourceCode":"\tif token.AccessorID != \"\" {\n\t\treturn nil, nil, errors.New(\"cannot specify Accessor ID\")\n\t}\n\tvar resp ACLToken\n\twm, err := a.client.put(\"/v1/acl/token\", token, &resp, q)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn &resp, wm, nil\n}\n\n// Upload is used to create a client token with pre-specified AccessorID and\n// SecretID. Management tokens cannot be uploaded and must be created with Create.\nfunc (a *ACLTokens) Upload(token *ACLToken, q *WriteOptions) (*ACLToken, *WriteMeta, error) {\n\tif token.AccessorID == \"\" {\n\t\treturn nil, nil, errors.New(\"missing accessor ID\")\n\t}\n\tif token.SecretID == \"\" {\n\t\treturn nil, nil, errors.New(\"missing secret ID\")\n\t}\n\tif token.Type == \"management\" {\n\t\treturn nil, nil, errors.New(\"cannot upload management tokens\")\n\t}\n\tvar resp ACLToken\n\twm, err := a.client.put(\"/v1/acl/token/\"+token.AccessorID, token, &resp, q)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn &resp, wm, nil\n}\n\n// Update is used to update an existing token\nfunc (a *ACLTokens) Update(token *ACLToken, q *WriteOptions) (*ACLToken, *WriteMeta, error) {\n\tif token.AccessorID == \"\" {\n\t\treturn nil, nil, errors.New(\"missing accessor ID\")\n\t}\n\tvar resp ACLToken","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/api/acl.go#L132-L168","documentation":"The Create endpoint (CSI volume create/`nomad volume create`) requires at least one volume definition in the request's Volumes list. An empty request is rejected before any validation or plugin RPC occurs.","triggerScenarios":"Calling the Create RPC (POST /v1/volumes/create or SDK equivalent) with an empty or omitted Volumes array; templated HCL that rendered to zero volume blocks.","commonSituations":"HCL file with only `type = \"csi\"` but no volume stanza; variable interpolation producing empty list; scripting the HTTP API and forgetting the JSON body.","solutions":["Include at least one volume block in the request (nomad volume create file.hcl with a `volume` stanza)","Verify the HCL/JSON file actually contains volume definitions and parses correctly","Check templating output (consul-template/nomad var rendering) isn't dropping the volume blocks"],"exampleFix":"# before: file with no volume blocks\nid   = \"ebs-vol\"\ntype = \"csi\"\n# after\nid   = \"ebs-vol\"\ntype = \"csi\"\nvolume {\n  plugin_id      = \"aws-ebs\"\n  capacity_min   = \"10GiB\"\n  capacity_max   = \"20GiB\"\n  capability { access_mode = \"single-node-writer\" attachment_mode = \"file-system\" }\n}","handlingStrategy":"validation","validationCode":"// client-side check before calling Create\nif len(request.Volumes) == 0 {\n    return fmt.Errorf(\"at least one volume definition required\")\n}","typeGuard":null,"tryCatchPattern":"if err := create(req); err != nil && strings.Contains(err.Error(), \"missing volume definition\") {\n    // fix request payload: include >=1 volume block\n}","preventionTips":["Validate rendered HCL/JSON templates contain volume blocks","Test `nomad volume create file.hcl` output with nomad job validate-style dry runs","Always send a populated Volumes array in API scripts"],"tags":["nomad","csi","validation","api-request"],"backgroundTag":"missing-request-payload","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"}