{"record":{"id":"4d7f451acd786970","repo":"hashicorp/nomad","slug":"secret-name-cannot-be-empty","errorCode":null,"errorMessage":"secret name cannot be empty","messagePattern":"secret name cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":10631,"sourceCode":"\n\treturn &Secret{\n\t\tName:     s.Name,\n\t\tProvider: s.Provider,\n\t\tPath:     s.Path,\n\t\tConfig:   confCopy.(map[string]any),\n\t\tEnv:      maps.Clone(s.Env),\n\t}\n}\n\nfunc (s *Secret) Validate() error {\n\tif s == nil {\n\t\treturn nil\n\t}\n\n\tvar mErr multierror.Error\n\n\tif s.Name == \"\" {\n\t\t_ = multierror.Append(&mErr, errors.New(\"secret name cannot be empty\"))\n\t}\n\n\tif !validSecretName.MatchString(s.Name) {\n\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"secret name must match regex %s\", validSecretName))\n\t}\n\n\tif s.Provider == \"\" {\n\t\t_ = multierror.Append(&mErr, errors.New(\"secret provider cannot be empty\"))\n\t}\n\n\tif s.Path == \"\" {\n\t\t_ = multierror.Append(&mErr, errors.New(\"secret path cannot be empty\"))\n\t}\n\n\tif s.Provider == \"nomad\" || s.Provider == \"vault\" {\n\t\tif len(s.Env) > 0 {\n\t\t\t_ = multierror.Append(&mErr, fmt.Errorf(\"%s provider cannot use the env block\", s.Provider))\n\t\t}","sourceCodeStart":10613,"sourceCodeEnd":10649,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L10613-L10649","documentation":"This error comes from the secrets (variable/secret) struct validation: a secret entry must have a non-empty Name. The validator appends this error when s.Name is \"\"; a companion check enforces the name matches validSecretName regex. The DECLARED AS note pointing at acl/acl.go is unrelated boilerplate — the source region here is the secret validation method in structs.go.","triggerScenarios":"Creating/submitting a secret (via the secrets API endpoint or CLI) with an empty name field, or constructing the Secret struct in Go with Name unset and calling its Validate/Check path.","commonSituations":"API clients that build the JSON payload programmatically and leave the name key empty; CLI wrappers mapping user input where the name flag was omitted; automation that derives names from templates that rendered empty.","solutions":["Provide a non-empty secret name that also matches the required regex (alphanumeric with dashes/underscores, per validSecretName).","If the name is user-supplied, validate/trim input before calling the API.","Check the payload field name — a typo like 'secretName' vs 'name' can leave Name empty after unmarshal.","Return a clear client-side error instead of hitting the API when name is blank."],"exampleFix":"// before\ncurl -X POST .../secrets -d '{\"provider\":\"vault\",\"path\":\"kv/app\"}'\n// after\ncurl -X POST .../secrets -d '{\"name\":\"app-credentials\",\"provider\":\"vault\",\"path\":\"kv/app\"}'","handlingStrategy":"validation","validationCode":"var validSecretName = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_-]*$`)\nfunc validateSecretName(name string) error {\n\tif name == \"\" {\n\t\treturn fmt.Errorf(\"secret name cannot be empty\")\n\t}\n\tif !validSecretName.MatchString(name) {\n\t\treturn fmt.Errorf(\"secret name %q does not match required pattern\", name)\n\t}\n\treturn nil\n}","typeGuard":"func hasSecretName(s *structs.Secret) bool { return s != nil && s.Name != \"\" }","tryCatchPattern":"if err := secret.Validate(); err != nil {\n\tif strings.Contains(err.Error(), \"secret name cannot be empty\") {\n\t\treturn fmt.Errorf(\"please provide --name for the secret\")\n\t}\n\treturn err\n}","preventionTips":["Require the name flag/field at the CLI/API boundary.","Trim whitespace from user-supplied names before submission.","Check JSON key spelling (\"name\") when building payloads dynamically."],"tags":["nomad","secrets","validation"],"backgroundTag":"missing-required-argument","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"}