nats-io/nats-server · error
variable reference for '%s' on line %d can not be found
Error message
variable reference for '%s' on line %d can not be found
What it means
A variable reference item was syntactically valid but lookupVariable could not find a value in any context map, in the config, or in the process environment (os.LookupEnv). The reference resolves to nothing, so parsing aborts with the reference name and line number.
Source
Thrown at conf/parse.go:390
return fmt.Errorf(
"expected Zulu formatted DateTime, but got '%s'", it.val)
}
setValue(it, dt)
case itemArrayStart:
var array = make([]any, 0)
p.pushContext(array)
case itemArrayEnd:
array := p.ctx
p.popContext()
setValue(it, array)
case itemVariable:
value, found, err := p.lookupVariable(it.val)
if err != nil {
return fmt.Errorf("variable reference for '%s' on line %d could not be parsed: %s",
it.val, it.line, err)
}
if !found {
return fmt.Errorf("variable reference for '%s' on line %d can not be found",
it.val, it.line)
}
if p.pedantic {
switch tk := value.(type) {
case *token:
// Mark the looked up variable as used, and make
// the variable reference become handled as a token.
tk.usedVariable = true
p.setValue(&token{it, tk.Value(), false, fp})
default:
// Special case to add position context to bcrypt references.
p.setValue(&token{it, value, false, fp})
}
} else {
p.setValue(value)
}
case itemInclude:View on GitHub (pinned to 3a66a489d2)
Solutions
- Define the referenced key in the config file or push it into the config context before parsing.
- Export the environment variable before running the process (os.LookupEnv is consulted as fallback).
- Fix typos in the reference name (error includes the name and line number).
- Provide a default value at the call site instead of relying on an unset variable.
- In CI/CD, ensure the variable is passed into the job/container environment.
Example fix
// before (VAR unset)
secret = ${API_SECRET}
// after
export API_SECRET=... # or define in config:
API_SECRET = literal-value
secret = ${API_SECRET} Defensive patterns
Strategy: try-catch
Validate before calling
name := "API_SECRET"
if os.LookupEnv(name) == nil {
return fmt.Errorf("required variable %s is not set", name)
} Try / catch
var perr interface{ }
if err := parseConfig(); err != nil {
if strings.Contains(err.Error(), "can not be found") {
// resolve the missing variable or abort with a clear setup message
return fmt.Errorf("config setup incomplete: %w", err)
}
return err
} Prevention
- Document and check all required env vars at process startup.
- Provide defaults for optional variables.
- Keep variable definitions before their references in include order.
- Verify CI/CD passes the same env vars as local dev.
When it happens
Trigger: processItem (from parse) hits case itemVariable where lookupVariable returns found=false: the referenced key is absent from all pushed contexts, the included config, and the OS environment.
Common situations: Referencing an env var that was never exported (or only set in a different shell/CI stage), typo in the variable name, dependency on a variable set by a deployment manifest that isn't present locally, or referencing a config key defined after the reference in an include file.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- variable reference for '%s' on line %d could not be parsed:
- variable reference cycle for '%s'
- mqtt authentication token not compatible with presence of us
- ack wait must be a positive value
- JS API timeout must be a positive value
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/361a92de9b11150c.
Report an issue: GitHub.