hashicorp/nomad · error
error parsing: root should be an object
Error message
error parsing: root should be an object
What it means
decodeHostVolume expects the parsed HCL input file to be an ObjectList (i.e. the top level of the HCL body is made of key/value blocks or attributes). When hclparse yields an *ast.File whose Node is not an *ast.ObjectList — for example an empty document or a bare literal — the command refuses to decode it and returns this error instead of panicking on the type assertion.
Source
Thrown at command/volume_create_host.go:216
})
if err != nil {
return err
}
if vol.State == api.HostVolumeStateReady {
c.Ui.Info(fmt.Sprintf("==> %s: Volume %q ready",
formatTime(time.Now()), limit(vol.Name, opts.length)))
return nil
}
}
}
func decodeHostVolume(input *ast.File) (*api.HostVolume, error) {
var err error
vol := &api.HostVolume{}
list, ok := input.Node.(*ast.ObjectList)
if !ok {
return nil, fmt.Errorf("error parsing: root should be an object")
}
// Decode the full thing into a map[string]interface for ease
var m map[string]any
err = hcl.DecodeObject(&m, list)
if err != nil {
return nil, err
}
// Need to manually parse these fields/blocks
delete(m, "capability")
delete(m, "constraint")
delete(m, "capacity")
delete(m, "capacity_max")
delete(m, "capacity_min")
delete(m, "type")
// Decode the restView on GitHub (pinned to 482b49bf1a)
Solutions
- Ensure the HCL file has at least one top-level `key = value` or `block { ... }` construct so the root parses as an object
- Verify the file path passed to the volume create command points to an HCL host-volume spec, not a job file, JSON array, or empty file
- Add a top-level attribute (e.g. `name = "..."`, `type = "host"`) to the spec
- Run `hclfmt` or the Nomad job validate/inspect equivalents to sanity-check the file parses to an object
Example fix
// before (empty or literal-only file) "my-volume" // after (proper HCL object root) name = "my-volume" type = "host" capacity = "10GiB" host_volume = "shared-csi-host-volume"
Defensive patterns
Strategy: validation
Validate before calling
func looksLikeHCLObject(input string) error {
parsed, err := hcl.Parse(input)
if err != nil {
return err
}
if _, ok := parsed.Node.(*ast.ObjectList); !ok {
return fmt.Errorf("volume spec root must be an HCL object (key = value / block { ... }), got %T", parsed.Node)
}
return nil
}
// call before handing the file to `nomad volume create` Type guard
func isObjectList(f *ast.File) bool {
_, ok := f.Node.(*ast.ObjectList)
return ok
} Try / catch
vol, err := decodeHostVolume(input)
if err != nil {
if strings.Contains(err.Error(), "root should be an object") {
return fmt.Errorf("volume file %s is empty or not an HCL object; check the file contents", path)
}
return err
} Prevention
- Always include at least one top-level attribute or block in the volume spec
- Verify the file path before invoking the volume command (non-empty, text, HCL)
- Never pass JSON arrays or YAML to the HCL volume loader
- Lint specs with hclfmt in CI
When it happens
Trigger: Calling `nomad volume create` (hostVolumeCreate/hostVolumeRegister) with an HCL volume spec whose root is not an object: an empty file, a file containing only a bare string/number, or non-HCL content that still parses (e.g. a JSON array at top level).
Common situations: Accidentally passing a YAML or JSON list file to the volume command; pointing the -volume flag at an empty file; copy/paste errors that drop all top-level keys; invoking the command with a path whose contents are binary or a lockfile.
Related errors
- <combined HCL diagnostics from str.String()>
- error parsing HTTPReadTimeout: %w
- failed to parse HCL file %s: %w
- Unable to parse job submission to re-enable scaling policies
- error parsing: root should be an object
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/102ac72ae9a0b2ae.
Report an issue: GitHub.