{"record":{"id":"774b9c85577004b3","repo":"hashicorp/nomad","slug":"secret-q-is-invalid-w","errorCode":null,"errorMessage":"Secret %q is invalid: %w","messagePattern":"Secret %q is invalid: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":8457,"sourceCode":"\t\tif err := wid.Validate(); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Identity %q is invalid: %w\", wid.Name, err))\n\t\t}\n\t}\n\n\tsecrets := make(map[string]bool)\n\tfor _, s := range t.Secrets {\n\t\tif _, ok := secrets[s.Name]; ok {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Duplicate secret %q found\", s.Name))\n\t\t} else {\n\t\t\tsecrets[s.Name] = true\n\t\t}\n\n\t\tif s.Provider == SecretProviderVault && t.Vault == nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Secret %q has provider \\\"vault\\\" but no vault block\", s.Name))\n\t\t}\n\n\t\tif err := s.Validate(); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Secret %q is invalid: %w\", s.Name, err))\n\t\t}\n\t}\n\n\treturn mErr.ErrorOrNil()\n}\n\n// validateServices takes a task and validates the services within it are valid\n// and reference ports that exist.\nfunc validateServices(t *Task, tgNetworks Networks) error {\n\tvar mErr multierror.Error\n\n\t// Ensure that services don't ask for nonexistent ports and their names are\n\t// unique.\n\tservicePorts := make(map[string]map[string]struct{})\n\taddServicePort := func(label, service string) {\n\t\tif _, ok := servicePorts[label]; !ok {\n\t\t\tservicePorts[label] = map[string]struct{}{}\n\t\t}","sourceCodeStart":8439,"sourceCodeEnd":8475,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L8439-L8475","documentation":"Each task secret is validated by Secret.Validate; failures are wrapped as 'Secret %q is invalid: %w' in Task.Validate. The inner error describes the specific problem: empty name, invalid provider, missing/invalid path, or bad identity configuration for the provider.","triggerScenarios":"secrets { } block with an empty name, unsupported provider string, malformed path (e.g. missing key), or a provider like \"vault\" whose required fields are absent; the wrapped %w carries the precise cause.","commonSituations":"Typos in provider name (\"Vault\", \"nomad\"); path missing the key segment (\"kv/data/db\" without key for KV v1); secrets defined via generated jobspec where fields were interpolated to empty strings.","solutions":["Read the wrapped inner error after 'is invalid:' to find the failing field","Ensure name and provider are set to valid values and path includes the secret key","Validate locally with `nomad job validate` and fix the offending block","Check provider docs (vault/nomad) for required fields"],"exampleFix":"// before\nsecrets {\n  provider = \"vault\"\n  path     = \"kv/data/db\"\n}\n// after\nsecrets {\n  name     = \"db_password\"\n  provider = \"vault\"\n  path     = \"kv/data/db#password\"\n}","handlingStrategy":"validation","validationCode":"for _, s := range t.Secrets {\n    if err := s.Validate(); err != nil {\n        return fmt.Errorf(\"secret %q bad: %w\", s.Name, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := job.Validate(); err != nil {\n    // surface wrapped 'Secret %q is invalid:' causes to the user\n}","preventionTips":["Set name, a supported provider, and a full path including key","Avoid empty interpolated fields in generated secret blocks","Run `nomad job validate` before every submit"],"tags":["nomad","secrets","validation"],"backgroundTag":"secret-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"}