{"record":{"id":"a28591d19c381a02","repo":"hashicorp/nomad","slug":"failed-to-decode-driver-config-v","errorCode":null,"errorMessage":"failed to decode driver config: %v","messagePattern":"failed to decode driver config: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/docker/driver.go","lineNumber":338,"sourceCode":"func loggingIsEnabled(driverCfg *DriverConfig, taskCfg *drivers.TaskConfig) bool {\n\tif driverCfg.DisableLogCollection {\n\t\treturn false\n\t}\n\tif taskCfg.StderrPath == os.DevNull && taskCfg.StdoutPath == os.DevNull {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drivers.DriverNetwork, error) {\n\tif _, ok := d.tasks.Get(cfg.ID); ok {\n\t\treturn nil, nil, fmt.Errorf(\"task with ID %q already started\", cfg.ID)\n\t}\n\n\tvar driverConfig TaskConfig\n\n\tif err := cfg.DecodeDriverConfig(&driverConfig); err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to decode driver config: %v\", err)\n\t}\n\n\tif driverConfig.Image == \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"image name required for docker driver\")\n\t}\n\n\tdriverConfig.Image = strings.TrimPrefix(driverConfig.Image, \"https://\")\n\n\tdriverConfig.ImagePullTimeout = getValue(driverConfig.ImagePullTimeout, d.config.ImagePullTimeout)\n\n\thandle := drivers.NewTaskHandle(taskHandleVersion)\n\thandle.Config = cfg\n\n\t// we'll need the normal docker client\n\tdockerClient, err := d.getDockerClient()\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"Failed to create docker client: %v\", err)\n\t}","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/drivers/docker/driver.go#L320-L356","documentation":"StartTask decodes the driver-specific task configuration block from the TaskConfig via cfg.DecodeDriverConfig into a TaskConfig struct. This error wraps whatever decoding failure occurred (wrong types, unknown fields with strict decoding, malformed hcl/job spec). It means the task's driver config could not be converted into the Docker driver's expected schema.","triggerScenarios":"Submitting a job whose docker driver 'config' block does not conform to TaskConfig (e.g. image given as a non-string, port_map with wrong type, args as a string instead of list) so DecodeDriverConfig returns an error, which StartTask wraps verbatim.","commonSituations":"Typo or wrong type in a Nomad job HCL/JSON docker config stanza; passing config produced for another driver (e.g. exec) to the docker driver; API/tooling generating JSON job specs with wrong field types; schema changes across Nomad versions making old fields invalid.","solutions":["Read the wrapped inner error (%v) to identify the exact field/type mismatch and fix the task's driver config block accordingly","Validate the job spec locally (nomad job validate) before submission","Ensure the config block targets the docker driver schema: image must be a string, args/port_map/auth fields must match TaskConfig types","If upgrading Nomad, check for removed/renamed docker driver config fields and update the job file"],"exampleFix":"// before (job spec)\nconfig {\n  image = 42          // wrong type\n  args   = \"foo\"      // wrong type: must be a list\n}\n// after\nconfig {\n  image = \"nginx:1.25\"\n  args   = [\"foo\"]\n}","handlingStrategy":"validation","validationCode":"// validate driver config before submission\n// $ nomad job validate job.nomad\n// or programmatically ensure the config block matches docker driver schema:\nif cfg[\"image\"] == nil || reflect.TypeOf(cfg[\"image\"]).Kind() != reflect.String {\n    return errors.New(\"docker config.image must be a string\")\n}","typeGuard":"func dockerConfigHasValidImage(cfg map[string]interface{}) bool {\n    img, ok := cfg[\"image\"].(string)\n    return ok && img != \"\"\n}","tryCatchPattern":"if _, _, err := driver.StartTask(cfg); err != nil {\n    if strings.HasPrefix(err.Error(), \"failed to decode driver config\") {\n        // log wrapped cause, fix the task's config block; retry is futile without change\n        return fmt.Errorf(\"invalid docker driver config: %w\", err)\n    }\n    return err\n}","preventionTips":["Run nomad job validate on every job spec before submit (CI gate)","Match field names and types exactly to the docker driver TaskConfig schema","Keep job specs updated when upgrading Nomad (check docker driver config deprecations)","Avoid generating driver config JSON by hand; use typed structs or validated templates"],"tags":["docker","nomad-driver","config-decode","hcl"],"backgroundTag":"schema-validation-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}