hashicorp/nomad · critical

failed to convert HCL schema:

Error message

failed to convert HCL schema: 

What it means

In plugins/shared/cmd/launcher/command/device.go:183 (getSpec, called by Run), the device plugin launcher converts its HCL spec (hclspecutils.Convert) into a schema. If the returned diagnostics contain errors, it builds a message starting with 'failed to convert HCL schema: ' followed by each diagnostic on its own '* ' line. It means the device plugin's declared config schema itself is invalid HCL-spec — a plugin-side defect, not user config.

Source

Thrown at plugins/shared/cmd/launcher/command/device.go:183

	dev := raw.(device.DevicePlugin)
	return dev, func() { client.Kill() }, nil
}

func (c *Device) getSpec() (hcldec.Spec, error) {
	// Get the schema so we can parse the config
	spec, err := c.dev.ConfigSchema()
	if err != nil {
		return nil, fmt.Errorf("failed to get config schema: %v", err)
	}

	// Convert the schema
	schema, diag := hclspecutils.Convert(spec)
	if diag.HasErrors() {
		errStr := "failed to convert HCL schema: "
		for _, err := range diag.Errs() {
			errStr = fmt.Sprintf("%s\n* %s", errStr, err.Error())
		}
		return nil, errors.New(errStr)
	}

	return schema, nil
}

func (c *Device) setConfig(spec hcldec.Spec, apiVersion string, config []byte, nmdCfg *base.AgentConfig) error {
	// Parse the config into hcl
	configVal, err := hclConfigToAny(config)
	if err != nil {
		return err
	}

	val, diag, diagErrs := hclutils.ParseHclInterface(configVal, spec, nil)
	if diag.HasErrors() {
		return multierror.Append(errors.New("failed to parse config: "), diagErrs...)
	}

	cdata, err := msgpack.Marshal(val, val.Type())

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Fix the plugin's hclspec definition so it converts cleanly (the appended diagnostics name the offending fields)
  2. Rebuild the plugin against the nomad plugin SDK version matching your Nomad client
  3. As a workaround, pin to a previously working plugin binary release

Example fix

// before
spec := hclspec.NewObject(map[string]*hclspec.Spec{
    "devices": nil, // invalid: nil spec causes conversion diagnostics
})
// after
spec := hclspec.NewObject(map[string]*hclspec.Spec{
    "devices": hclspec.NewAttr("devices", "list(string)", false),
})
Defensive patterns

Strategy: fallback

Validate before calling

// preflight: run the plugin's spec conversion in a test
_, diag := hclspecutils.Convert(pluginSpec)
if diag.HasErrors() { t.Fatalf("invalid plugin spec: %v", diag.Errs()) }

Try / catch

schema, err := getSpec(spec)
if err != nil {
    return fmt.Errorf("device plugin spec invalid: %w — rebuild/rollback plugin", err)
}

Prevention

When it happens

Trigger: Running a device plugin whose GetDevicePluginSpec/hclspec definition fails to compile into a valid HCL schema, e.g. malformed hclspec protobuf fields, unsupported spec types, or contradictory attribute definitions in the plugin binary.

Common situations: Developing a custom Nomad device plugin with a broken hclspec; plugin built against mismatched nomad-plugin API versions where a spec construct is no longer supported; shipping a plugin with a typo in its spec declaration.

Related errors


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