hashicorp/nomad · warning · ErrVariablePathNotFound
variable not found
Error message
variable not found
What it means
ErrVariablePathNotFound is the sentinel error (message "variable not found") returned by Variables().Read and Variables().GetVariableItems when the queried variable path does not exist on the server — the API returns no variable and readInternal yields a nil v. It is exported so callers can compare with errors.Is instead of matching strings.
Source
Thrown at api/variables.go:25
"encoding/json"
"errors"
"fmt"
"maps"
"net/http"
"strings"
)
const (
// ErrVariableNotFound was used as the content of an error string.
//
// Deprecated: use ErrVariablePathNotFound instead.
ErrVariableNotFound = "variable not found"
)
var (
// ErrVariablePathNotFound is returned when trying to read a variable that
// does not exist.
ErrVariablePathNotFound = errors.New("variable not found")
)
// Variables is used to access variables.
type Variables struct {
client *Client
}
// Variables returns a new handle on the variables.
func (c *Client) Variables() *Variables {
return &Variables{client: c}
}
// Create is used to create a variable.
func (vars *Variables) Create(v *Variable, qo *WriteOptions) (*Variable, *WriteMeta, error) {
v.Path = cleanPathString(v.Path)
var out Variable
wm, err := vars.client.put("/v1/var/"+v.Path, v, &out, qo)
if err != nil {View on GitHub (pinned to 482b49bf1a)
Solutions
- Verify the exact variable path (including namespace and 'nomad/jobs/...' prefix) with nomad var list or the UI.
- Create the variable first via Create/Update (or `nomad var put`) before reading.
- Compare with errors.Is(err, api.ErrVariablePathNotFound) and provide a default/fallback instead of failing.
- Check the QueryOptions.Namespace matches where the variable lives, and that the token's ACL grants read on it.
Example fix
// before
v, _, err := client.Variables().Read("nomad/jobs/app/config", nil)
if err != nil { return err }
// after
v, _, err := client.Variables().Read("nomad/jobs/app/config", nil)
if errors.Is(err, api.ErrVariablePathNotFound) {
v = defaultVar // fall back when the variable doesn't exist yet
} else if err != nil {
return err
} Defensive patterns
Strategy: type-guard
Validate before calling
import "errors"
import "github.com/hashicorp/nomad/api"
// pre-check via List to see if the path exists
vars, _, err := client.Variables().List(nil, nil)
exists := false
if err == nil {
for _, v := range vars {
if v.Path == "nomad/jobs/app/config" { exists = true; break }
}
} Type guard
func isVarNotFound(err error) bool {
return errors.Is(err, api.ErrVariablePathNotFound)
} Try / catch
v, _, err := client.Variables().Read(path, nil)
switch {
case errors.Is(err, api.ErrVariablePathNotFound):
v = createOrUseDefault(path)
case err != nil:
return err
} Prevention
- Always use errors.Is(err, api.ErrVariablePathNotFound) rather than string comparison.
- Create variables (nomad var put) before jobs/templates that read them.
- Double-check path spelling, namespace, and required prefixes like nomad/jobs/.
- Verify the ACL token can read the variable in the target namespace.
When it happens
Trigger: Calling client.Variables().Read(path, q) or GetVariableItems(path, q) for a path that was never created or was deleted/purged; reading a path in a namespace where it doesn't exist; a typo in the variable path (e.g. wrong namespace prefix or missing 'nomad/jobs' segment).
Common situations: Job templates reading variables whose path was misconfigured; CI reading a variable before the provisioning step that creates it; ACL/namespace differences making an existing variable invisible to the caller's token; GC removing stale job variables.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0c8fb5a5042159f4.
Report an issue: GitHub.