{"record":{"id":"23589f2ecfd0e9a9","repo":"hashicorp/nomad","slug":"error-parsing-consul-w","errorCode":null,"errorMessage":"error parsing 'consul': %w","messagePattern":"error parsing 'consul': %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/config_parse.go","lineNumber":96,"sourceCode":"\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{\n\t\t{\"gc_interval\", &c.Client.GCInterval, &c.Client.GCIntervalHCL, nil},\n\t\t{\"acl.token_ttl\", &c.ACL.TokenTTL, &c.ACL.TokenTTLHCL, nil},\n\t\t{\"acl.policy_ttl\", &c.ACL.PolicyTTL, &c.ACL.PolicyTTLHCL, nil},\n\t\t{\"acl.policy_ttl\", &c.ACL.RoleTTL, &c.ACL.RoleTTLHCL, nil},\n\t\t{\"acl.token_min_expiration_ttl\", &c.ACL.TokenMinExpirationTTL, &c.ACL.TokenMinExpirationTTLHCL, nil},\n\t\t{\"acl.token_max_expiration_ttl\", &c.ACL.TokenMaxExpirationTTL, &c.ACL.TokenMaxExpirationTTLHCL, nil},","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/config_parse.go#L78-L114","documentation":"ParseConfigFile filters 'consul' blocks and passes them to parseConsuls; this error wraps any failure from that function. parseConsuls requires each consul block to be an object and decodes nested service_identity/template_identity blocks.","triggerScenarios":"Calling ParseConfigFile/LoadConfig on a config with a `consul { ... }` block whose value is not an object type (e.g. `consul = 5`), or whose nested service_identity/template_identity blocks fail hcl.DecodeObject.","commonSituations":"Typo turning a consul block into an assignment; YAML-to-HCL conversion producing wrong syntax; editing consul stanza by hand and dropping braces.","solutions":["Write `consul` as a braced block: `consul { address = \"127.0.0.1:8500\" }`","Verify nested service_identity/template_identity blocks are objects with valid syntax","Run a syntax check / the agent with the config to get the wrapped underlying error message","Restore the consul stanza from a known-good template"],"exampleFix":"// before\nconsul = \"127.0.0.1:8500\"\n\n// after\nconsul {\n  address = \"127.0.0.1:8500\"\n}","handlingStrategy":"validation","validationCode":"func validateConsulBlock(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(\"consul\").Items {\n\t\tif _, ok := item.Val.(*ast.ObjectType); !ok {\n\t\t\treturn fmt.Errorf(\"consul must be a braced block\")\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func isConsulBlock(obj *ast.ObjectItem) bool {\n\t_, ok := obj.Val.(*ast.ObjectType)\n\treturn ok\n}","tryCatchPattern":"cfg, err := ParseConfigFile(path)\nif err != nil {\n\tif strings.Contains(err.Error(), \"error parsing 'consul'\") {\n\t\treturn fmt.Errorf(\"invalid consul stanza in %s: %w\", path, err)\n\t}\n\treturn err\n}","preventionTips":["Write consul as a braced block with key = value lines inside","Check nested service_identity/template_identity blocks are objects","Validate configs in CI before rollout","Restore stanzas from templates rather than free-hand edits"],"tags":["hcl","config-parsing","consul"],"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"}