hashicorp/nomad · error
secret path cannot be empty
Error message
secret path cannot be empty
What it means
This error is returned by SecureVariableMessian/Variable validation (structs.go) when a secret/variable entry declares a provider but has an empty Path. Nomad requires every templated secret reference to name both a provider and a path within that provider; a missing path makes the reference unresolvable. It is appended to a multierror alongside other field-level validation failures, so it may appear with more errors at once.
Source
Thrown at nomad/structs/structs.go:10643
return nil
}
var mErr multierror.Error
if s.Name == "" {
_ = multierror.Append(&mErr, errors.New("secret name cannot be empty"))
}
if !validSecretName.MatchString(s.Name) {
_ = multierror.Append(&mErr, fmt.Errorf("secret name must match regex %s", validSecretName))
}
if s.Provider == "" {
_ = multierror.Append(&mErr, errors.New("secret provider cannot be empty"))
}
if s.Path == "" {
_ = multierror.Append(&mErr, errors.New("secret path cannot be empty"))
}
if s.Provider == "nomad" || s.Provider == "vault" {
if len(s.Env) > 0 {
_ = multierror.Append(&mErr, fmt.Errorf("%s provider cannot use the env block", s.Provider))
}
} else {
if len(s.Config) > 0 {
_ = multierror.Append(&mErr, fmt.Errorf("custom plugin provider %s cannot use the config block", s.Provider))
}
}
return mErr.ErrorOrNil()
}
func (s *Secret) Canonicalize() {
if s == nil {
returnView on GitHub (pinned to 482b49bf1a)
Solutions
- Set the Path field on the secret/variable struct (or the path = "..." argument in the template/secret stanza) to the secret's location, e.g. "secret/data/myapp".
- If the secret is not needed, remove the whole secret block rather than leaving a provider with an empty path.
- Inspect the full multierror response for sibling errors (provider empty, env block misuse) and fix them in the same submit.
Example fix
// before
sec := &structs.SecureVariableMessian{Provider: "vault"}
// after
sec := &structs.SecureVariableMessian{Provider: "vault", Path: "secret/data/app/config"} Defensive patterns
Strategy: validation
Validate before calling
func validSecret(s *structs.Variable) bool {
return s != nil && s.Provider != "" && s.Path != ""
}
if !validSecret(sec) {
return fmt.Errorf("secret requires provider and path")
} Type guard
func hasPath(s interface{ GetPath() string }) bool { return s != nil && s.GetPath() != "" } Prevention
- Always pair provider with path in secret/variable stanzas
- Run `nomad job validate` before submitting jobs
- Check the full multierror list, not just the first message
When it happens
Trigger: Submitting a job, variable, or CSI/secret configuration where the block sets Provider (e.g. "vault" or "nomad") but leaves Path empty; calling Check/NewACL paths that validate a secret struct via its Validate() method with Path == "".
Common situations: Hand-written HCL/JSON job files with a template stanza referencing a secret but omitting the path argument; programmatically constructed structs in tests or tooling where only Provider was filled; copy-pasted configs where the path line was deleted.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- namespace cannot contain template delimiters or parenthesis
- wait config is nil or empty
- missing datacenter for client registration
- default_identity_ttl must be greater than 0
- max_identity_ttl must be greater than 0
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/db48c688e1a833c0.
Report an issue: GitHub.