hashicorp/nomad · error
failed to decode HCL file %s: %w
Error message
failed to decode HCL file %s: %w
What it means
ParseConfigFile reads the config file and decodes it into a Config struct via hcl.Decode. If HCL decoding fails (valid text but structure/types don't match the Config schema), the error is wrapped as 'failed to decode HCL file <path>'.
Source
Thrown at command/agent/config_parse.go:74
},
Server: &ServerConfig{
ClientIntroduction: &ClientIntroduction{},
PlanRejectionTracker: &PlanRejectionTracker{},
ServerJoin: &ServerJoin{},
},
ACL: &ACLConfig{},
RPC: &RPCConfig{},
Audit: &config.AuditConfig{},
Consuls: []*config.ConsulConfig{},
Autopilot: &config.AutopilotConfig{},
Telemetry: &Telemetry{},
Vaults: []*config.VaultConfig{},
Reporting: config.DefaultReporting(),
}
err = hcl.Decode(c, buf.String())
if err != nil {
return nil, fmt.Errorf("failed to decode HCL file %s: %w", path, err)
}
// Re-parse the file to extract the multiple Vault configurations, which we
// need to parse by hand because we don't have a label on the block
root, err := hcl.Parse(buf.String())
if err != nil {
return nil, fmt.Errorf("failed to parse HCL file %s: %w", path, err)
}
list, ok := root.Node.(*ast.ObjectList)
if !ok {
return nil, fmt.Errorf("error parsing: root should be an object")
}
matches := list.Filter("vault")
if len(matches.Items) > 0 {
if err := parseVaults(c, matches); err != nil {
return nil, fmt.Errorf("error parsing 'vault': %w", err)
}
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Read the wrapped %w error — it pinpoints the field/type that failed to decode
- Fix the value type to match the expected schema (e.g. numbers for ports, lists for bind addresses arrays)
- Check docs for your Consul version — schema differs across versions
- Run the file through hclfmt and compare with a known-good example config
Example fix
// before
ports { http = "8500" } // wrong type
// after
ports { http = 8500 } Defensive patterns
Strategy: validation
Validate before calling
src, err := os.ReadFile(path)
if err != nil { return err }
var probe map[string]interface{}
if err := hcl.Decode(&probe, string(src)); err != nil {
return fmt.Errorf("HCL decode pre-check failed: %w", err)
} Try / catch
cfg, err := agentcfg.ParseConfigFile(path)
if err != nil {
var derr *hcl.Error
if errors.As(err, &derr) {
return fmt.Errorf("fix types/keys near %v", derr)
}
return err
} Prevention
- Match key names and value types to the Config schema for your Consul version
- Don't copy config blocks between Consul versions without checking docs
- Run hclfmt + consul validate in CI
- Test configs in a dev agent before production rollout
When it happens
Trigger: A config file whose syntax parses but whose keys/types don't fit the Config struct — e.g. a value where a list is expected, unknown nested blocks, or type mismatches (string vs number) that hcl.Decode rejects.
Common situations: Wrong value types (ports as strings vs numbers depending on version), copy-pasted blocks from newer Consul versions into older ones, typos in block/keys causing mapping failures.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Error loading %s: %s
- failed to parse HCL file %s: %w
- failed to decode object: %v
- failed to convert task schema
- only one storage block is allowed
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/4b876f8b27ad9df9.
Report an issue: GitHub.