hashicorp/nomad · error

unable to parse var content

Error message

unable to parse var content: %v

What it means

When config.VarContent is non-empty, decode parses it as HCL/JSON (as 'input.hcl'). If the resulting diagnostics have errors, decode returns 'unable to parse var content: <diagnostics>', aborting jobspec parsing because the inline variable definitions are invalid.

Solutions

  1. Fix the HCL syntax error named in the wrapped diagnostics message.
  2. Validate the inline content by writing it to a temp .hcl file and running hclfmt/hcl2 parser on it.
  3. Check shell quoting when building VarContent from command-line flags.
  4. Prefer passing vars via a well-formed var file rather than concatenated inline content.

Example fix

// before (invalid inline content)
VarContent: "key=unquoted value with spaces"

// after
VarContent: "key = \"value with spaces\""
Defensive patterns

Strategy: validation

Validate before calling

if cfg.VarContent != "" {
    if _, diags := hclparse.ParseHCL([]byte(cfg.VarContent), "check.hcl"); diags.HasErrors() {
        return fmt.Errorf("invalid VarContent: %s", diags.Error())
    }
}

Try / catch

if err != nil && strings.Contains(err.Error(), "unable to parse var content") {
    // log the diagnostics; fix quoting/syntax before retry
}

Prevention

When it happens

Trigger: Passing VarContent (or -var style content collected by the caller) that is not valid HCL/JSON, e.g. missing quotes, wrong syntax, or invalid structure, then calling ParseWithConfig.

Common situations: CLI flag assembly bugs where multiple -var values are joined incorrectly; shell quoting stripping quotes; embedding JSON with trailing commas; key=value lines containing unescaped special characters.

Understand the failure class

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/e217709d8c1896d4. Report an issue: GitHub.

Appendix: source

Thrown at jobspec2/parse.go:150

func decode(c *jobConfig) error {
	config := c.ParseConfig

	file, diags := parseHCLOrJSON(config.Body, config.Path)

	for _, varFile := range config.VarFiles {
		parsedVarFile, ds := parseFile(varFile)
		if parsedVarFile == nil || ds.HasErrors() {
			return fmt.Errorf("unable to parse var file: %v", ds.Error())
		}

		config.parsedVarFiles = append(config.parsedVarFiles, parsedVarFile)
		diags = append(diags, ds...)
	}

	if config.VarContent != "" {
		hclFile, hclDiagnostics := parseHCLOrJSON([]byte(config.VarContent), "input.hcl")
		if hclDiagnostics.HasErrors() {
			return fmt.Errorf("unable to parse var content: %v", hclDiagnostics.Error())
		}
		config.parsedVarFiles = append(config.parsedVarFiles, hclFile)
	}

	// Return early if the input job or variable files are not valid.
	// Decoding and evaluating invalid files may result in unexpected results.
	if diags.HasErrors() {
		return diags
	}

	diags = append(diags, c.decodeBody(file.Body)...)

	if diags.HasErrors() {
		var str strings.Builder
		for i, diag := range diags {
			if i != 0 {
				str.WriteByte('\n')
			}

View on GitHub (pinned to 482b49bf1a)