{"record":{"id":"3982dc0e56482bb3","repo":"hashicorp/nomad","slug":"failed-to-parse-hcl-file-s-w","errorCode":null,"errorMessage":"failed to parse HCL file %s: %w","messagePattern":"failed to parse HCL file (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/config_parse.go","lineNumber":81,"sourceCode":"\t\tRPC:       &RPCConfig{},\n\t\tAudit:     &config.AuditConfig{},\n\t\tConsuls:   []*config.ConsulConfig{},\n\t\tAutopilot: &config.AutopilotConfig{},\n\t\tTelemetry: &Telemetry{},\n\t\tVaults:    []*config.VaultConfig{},\n\t\tReporting: config.DefaultReporting(),\n\t}\n\n\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","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/config_parse.go#L63-L99","documentation":"After decoding, ParseConfigFile re-parses the file with hcl.Parse to manually extract multiple 'vault' blocks (which lack labels). If the HCL text itself has a syntax error, hcl.Parse fails and the error is wrapped as 'failed to parse HCL file <path>'.","triggerScenarios":"Any HCL syntax error in the config file: unbalanced braces/brackets, missing commas or newlines between assignments, invalid tokens, or truncated files.","commonSituations":"Hand-edited .hcl files with unbalanced braces, merge conflicts left in config files, templating that emitted invalid HCL, or copy-paste dropping closing braces.","solutions":["Run hclfmt (or hcl2 linter) on the file — it reports the syntax error location","Check for unbalanced braces/brackets and missing commas around the reported line","Inspect the file for merge-conflict markers or truncation from failed deploys","Regenerate the file from a known-good template"],"exampleFix":"// before\nservice {\n  name = \"web\"\n// missing closing brace\n// after\nservice {\n  name = \"web\"\n}","handlingStrategy":"validation","validationCode":"src, err := os.ReadFile(path)\nif err != nil { return err }\nif _, err := hcl.Parse(string(src)); err != nil {\n    return fmt.Errorf(\"HCL syntax pre-check failed for %s: %w\", path, err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := hcl.Parse(string(src)); err != nil {\n    if pos := errPos(err); pos != nil {\n        return fmt.Errorf(\"syntax error at line %d: %w\", pos.Line, err)\n    }\n    return err\n}","preventionTips":["Run hclfmt as a pre-commit hook — it catches syntax errors early","Check for unbalanced braces after hand edits or merge conflicts","Reject merge-conflict markers in config via CI grep","Regenerate templated configs and diff against last-known-good"],"tags":["config","consul","hcl","syntax","parsing"],"backgroundTag":"hcl-syntax-error","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"}