hashicorp/nomad · error
should be an object
Error message
should be an object
What it means
parseVaults iterates each `vault` block and requires its value to be an *ast.ObjectType (a braced object). If the vault stanza is a scalar, list, or other non-object AST node, it returns 'should be an object', which ParseConfigFile wraps as "error parsing 'vault': should be an object".
Source
Thrown at command/agent/config_parse.go:502
c.Vaults[i] = exist.Merge(v)
vaultFound = true
break
}
}
if !vaultFound {
c.Vaults = append(c.Vaults, v)
}
for _, conf := range c.Vaults {
conf.Addr = ipaddr.NormalizeAddr(conf.Addr)
}
// Decode the default identity.
var listVal *ast.ObjectList
if ot, ok := obj.Val.(*ast.ObjectType); ok {
listVal = ot.List
} else {
return fmt.Errorf("should be an object")
}
if o := listVal.Filter("default_identity"); len(o.Items) > 0 {
var m map[string]any
defaultIdentityBlock := o.Items[0]
if err := hcl.DecodeObject(&m, defaultIdentityBlock.Val); err != nil {
return err
}
var defaultIdentity config.WorkloadIdentityConfig
if err := mapstructure.WeakDecode(m, &defaultIdentity); err != nil {
return err
}
v.DefaultIdentity = &defaultIdentity
}
}
return nilView on GitHub (pinned to 482b49bf1a)
Solutions
- Change `vault = <value>` to a block: `vault { address = "<value>" }`
- Check every `vault` occurrence in the file (multiple vault stanzas are supported; each must be an object)
- Re-run the agent after fixing to confirm the wrapped error is gone
Example fix
// before
vault = "https://vault.service.consul:8200"
// after
vault {
address = "https://vault.service.consul:8200"
} Defensive patterns
Strategy: validation
Validate before calling
func assertVaultIsBlock(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 not an object")
}
for _, v := range list.Filter("vault").Items {
if _, ok := v.Val.(*ast.ObjectType); !ok {
return fmt.Errorf("vault stanza must be `vault { ... }`")
}
}
return nil
} Type guard
func isObjectType(v ast.Node) bool {
_, ok := v.(*ast.ObjectType)
return ok
} Try / catch
cfg, err := ParseConfigFile(path)
if err != nil {
if strings.Contains(err.Error(), "should be an object") && strings.Contains(err.Error(), "'vault'") {
return fmt.Errorf("vault stanza in %s must be a block: vault { ... }", path)
}
return err
} Prevention
- Never assign a scalar directly to vault; always use braces
- Audit generated configs for `vault =` assignments
- Keep stanzas in templates that enforce block syntax
- Run the agent against configs in CI as a smoke test
When it happens
Trigger: A config file where `vault` appears but its value is not a braced block — e.g. `vault = "http://..."` or `vault = [1,2]` — reached via ParseConfigFile/LoadConfig.
Common situations: Assigning a string address directly to vault instead of nesting under a block; automated config generation emitting wrong syntax; merge conflicts resolving to an assignment instead of a block.
Related errors
- error parsing 'vault': %w
- 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/5599bf91f953660e.
Report an issue: GitHub.