{"record":{"id":"f5751783f8286cb7","repo":"hashicorp/nomad","slug":"failed-to-get-config-schema-v","errorCode":null,"errorMessage":"failed to get config schema: %v","messagePattern":"failed to get config schema: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/shared/cmd/launcher/command/device.go","lineNumber":173,"sourceCode":"\n\t// Request the plugin\n\traw, err := rpcClient.Dispense(base.PluginTypeDevice)\n\tif err != nil {\n\t\tclient.Kill()\n\t\treturn nil, nil, err\n\t}\n\n\t// We should have a KV store now! This feels like a normal interface\n\t// implementation but is in fact over an RPC connection.\n\tdev := raw.(device.DevicePlugin)\n\treturn dev, func() { client.Kill() }, nil\n}\n\nfunc (c *Device) getSpec() (hcldec.Spec, error) {\n\t// Get the schema so we can parse the config\n\tspec, err := c.dev.ConfigSchema()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get config schema: %v\", err)\n\t}\n\n\t// Convert the schema\n\tschema, diag := hclspecutils.Convert(spec)\n\tif diag.HasErrors() {\n\t\terrStr := \"failed to convert HCL schema: \"\n\t\tfor _, err := range diag.Errs() {\n\t\t\terrStr = fmt.Sprintf(\"%s\\n* %s\", errStr, err.Error())\n\t\t}\n\t\treturn nil, errors.New(errStr)\n\t}\n\n\treturn schema, nil\n}\n\nfunc (c *Device) setConfig(spec hcldec.Spec, apiVersion string, config []byte, nmdCfg *base.AgentConfig) error {\n\t// Parse the config into hcl\n\tconfigVal, err := hclConfigToAny(config)","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/plugins/shared/cmd/launcher/command/device.go#L155-L191","documentation":"getSpec obtains the device plugin's configuration schema via dev.ConfigSchema() so the launcher can parse device config. This error wraps any failure from that call, meaning the plugin could not supply a valid HCL spec schema.","triggerScenarios":"Calling Device.Run -> getSpec when the device plugin's ConfigSchema() returns an error, e.g. the plugin process is unhealthy, misconfigured, or its schema generation failed.","commonSituations":"Device plugin binary failing at startup or crashing; plugin returning a nil/invalid schema due to a bug; gRPC failure between the launcher and the device plugin; incompatible plugin/launcher versions.","solutions":["Read the wrapped %v error and check the device plugin's logs/stderr for the root cause.","Verify the device plugin binary runs standalone and is compatible with the launcher's plugin protocol.","Restart the device plugin process / re-provision plugin binaries.","If the plugin is custom, fix ConfigSchema() to return a valid hclspec.Spec without error."],"exampleFix":"// before\nfunc (d *MyDevice) ConfigSchema() (*hclspec.Spec, error) { return nil, fmt.Errorf(\"not ready\") }\n// after\nfunc (d *MyDevice) ConfigSchema() (*hclspec.Spec, error) {\n\treturn hclspec.NewBlockList(\"config\", configSpec), nil\n}","handlingStrategy":"retry","validationCode":"// Health-check the device plugin before requesting its schema\nif err := devicePluginPing(dev); err != nil {\n\treturn fmt.Errorf(\"device plugin not healthy: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"spec, err := c.getSpec()\nif err != nil && strings.Contains(err.Error(), \"failed to get config schema\") {\n\t// restart/reconnect the plugin, then retry once\n}","preventionTips":["Monitor device plugin process health and restart on crash.","Verify plugin binary compatibility with the launcher version.","Test custom devices' ConfigSchema() in unit tests.","Capture plugin stderr to diagnose the wrapped root cause quickly."],"tags":["plugin","device","config","schema"],"backgroundTag":"plugin-config-schema-failed","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"}