{"record":{"id":"0937e4a5d82a9556","repo":"hashicorp/nomad","slug":"error-parsing-vault-w","errorCode":null,"errorMessage":"error parsing 'vault': %w","messagePattern":"error parsing 'vault': %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/config_parse.go","lineNumber":90,"sourceCode":"\terr = hcl.Decode(c, buf.String())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode HCL file %s: %w\", path, err)\n\t}\n\n\t// Re-parse the file to extract the multiple Vault configurations, which we\n\t// need to parse by hand because we don't have a label on the block\n\troot, err := hcl.Parse(buf.String())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse HCL file %s: %w\", path, err)\n\t}\n\tlist, ok := root.Node.(*ast.ObjectList)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"error parsing: root should be an object\")\n\t}\n\tmatches := list.Filter(\"vault\")\n\tif len(matches.Items) > 0 {\n\t\tif err := parseVaults(c, matches); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error parsing 'vault': %w\", err)\n\t\t}\n\t}\n\tmatches = list.Filter(\"consul\")\n\tif len(matches.Items) > 0 {\n\t\tif err := parseConsuls(c, matches); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error parsing 'consul': %w\", err)\n\t\t}\n\t}\n\n\tmatches = list.Filter(\"keyring\")\n\tif len(matches.Items) > 0 {\n\t\tif err := parseKeyringConfigs(c, matches); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error parsing 'keyring': %w\", err)\n\t\t}\n\t}\n\n\t// convert strings to time.Durations\n\ttds := []durationConversionMap{","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/config_parse.go#L72-L108","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nvault = \"http://127.0.0.1:8200\"\n\n// after\nvault {\n  address = \"http://127.0.0.1:8200\"\n}","handlingStrategy":"validation","validationCode":"func validateVaultBlock(data []byte) error {\n\troot, err := hcl.Parse(string(data))\n\tif err != nil {\n\t\treturn err\n\t}\n\tlist, ok := root.Node.(*ast.ObjectList)\n\tif !ok {\n\t\treturn fmt.Errorf(\"root is not an object\")\n\t}\n\tfor _, item := range list.Filter(\"vault\").Items {\n\t\tif _, ok := item.Val.(*ast.ObjectType); !ok {\n\t\t\treturn fmt.Errorf(\"vault must be a braced block\")\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func isVaultBlock(obj *ast.ObjectItem) bool {\n\t_, ok := obj.Val.(*ast.ObjectType)\n\treturn ok\n}","tryCatchPattern":"cfg, err := ParseConfigFile(path)\nif err != nil {\n\tvar perr *parseErr\n\tif strings.Contains(err.Error(), \"error parsing 'vault'\") {\n\t\treturn fmt.Errorf(\"invalid vault stanza in %s: %w\", path, err)\n\t}\n\treturn err\n}","preventionTips":["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"],"tags":["hcl","config-parsing","vault"],"backgroundTag":"hcl-block-shape-invalid","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}