hashicorp/nomad · error
error parsing 'vault': %w
Error message
error parsing 'vault': %w
What it means
After the root AST is validated, ParseConfigFile filters out 'vault' blocks and passes them to parseVaults. This error wraps any failure from parseVaults, which itself validates block shape (must be an object) and decodes default_identity sub-blocks via hcl.DecodeObject.
Source
Thrown at command/agent/config_parse.go:90
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)
}
}
matches = list.Filter("consul")
if len(matches.Items) > 0 {
if err := parseConsuls(c, matches); err != nil {
return nil, fmt.Errorf("error parsing 'consul': %w", err)
}
}
matches = list.Filter("keyring")
if len(matches.Items) > 0 {
if err := parseKeyringConfigs(c, matches); err != nil {
return nil, fmt.Errorf("error parsing 'keyring': %w", err)
}
}
// convert strings to time.Durations
tds := []durationConversionMap{View on GitHub (pinned to 482b49bf1a)
Solutions
- Ensure `vault` is written as a block with braces: `vault { address = "..." }`, not `vault = "..."`
- Check nested blocks inside vault (e.g. default_identity) are objects with valid HCL syntax
- Validate the file with `vault agent -config=<file>` or hcl linter before deploying
- Compare against a known-good example config from the vault docs
Example fix
// before
vault = "http://127.0.0.1:8200"
// after
vault {
address = "http://127.0.0.1:8200"
} Defensive patterns
Strategy: validation
Validate before calling
func validateVaultBlock(data []byte) error {
root, err := hcl.Parse(string(data))
if err != nil {
return err
}
list, ok := root.Node.(*ast.ObjectList)
if !ok {
return fmt.Errorf("root is not an object")
}
for _, item := range list.Filter("vault").Items {
if _, ok := item.Val.(*ast.ObjectType); !ok {
return fmt.Errorf("vault must be a braced block")
}
}
return nil
} Type guard
func isVaultBlock(obj *ast.ObjectItem) bool {
_, ok := obj.Val.(*ast.ObjectType)
return ok
} Try / catch
cfg, err := ParseConfigFile(path)
if err != nil {
var perr *parseErr
if strings.Contains(err.Error(), "error parsing 'vault'") {
return fmt.Errorf("invalid vault stanza in %s: %w", path, err)
}
return err
} Prevention
- Always write vault as a braced block, never an assignment
- Keep nested default_identity blocks as objects with valid HCL syntax
- Validate configs in CI with the agent binary or an HCL linter
- Diff hand-edited stanzas against known-good examples
When it happens
Trigger: Calling ParseConfigFile/LoadConfig on a config containing a `vault { ... }` block that fails parsing — typically a vault block whose value is not an object (e.g. `vault = "foo"`) or whose nested default_identity block fails hcl.DecodeObject.
Common situations: Hand-edited config where `vault` was accidentally assigned a scalar or list instead of a block; copy-paste errors merging vault stanzas; wrong HCL syntax after a version upgrade of the config format.
Related errors
- should be an object
- error parsing: root should be an object
- error parsing 'consul': %w
- error parsing 'keyring': %w
- failed to decode key %q to string
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0937e4a5d82a9556.
Report an issue: GitHub.