{"record":{"id":"556966e2ebf192f6","repo":"hashicorp/nomad","slug":"failed-to-build-reattachconfig-from-taskconfig-sta-556966","errorCode":null,"errorMessage":"failed to build ReattachConfig from taskConfig state: %v","messagePattern":"failed to build ReattachConfig from taskConfig state: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/qemu/driver.go","lineNumber":309,"sourceCode":"\t// If already attached to handle there's nothing to recover.\n\tif _, ok := d.tasks.Get(handle.Config.ID); ok {\n\t\td.logger.Trace(\"nothing to recover; task already exists\",\n\t\t\t\"task_id\", handle.Config.ID,\n\t\t\t\"task_name\", handle.Config.Name,\n\t\t)\n\t\treturn nil\n\t}\n\n\tvar taskState TaskState\n\tif err := handle.GetDriverState(&taskState); err != nil {\n\t\td.logger.Error(\"failed to decode taskConfig state from handle\", \"error\", err, \"task_id\", handle.Config.ID)\n\t\treturn fmt.Errorf(\"failed to decode taskConfig state from handle: %v\", err)\n\t}\n\n\tplugRC, err := pstructs.ReattachConfigToGoPlugin(taskState.ReattachConfig)\n\tif err != nil {\n\t\td.logger.Error(\"failed to build ReattachConfig from taskConfig state\", \"error\", err, \"task_id\", handle.Config.ID)\n\t\treturn fmt.Errorf(\"failed to build ReattachConfig from taskConfig state: %v\", err)\n\t}\n\n\texecImpl, pluginClient, err := executor.ReattachToExecutor(\n\t\tplugRC,\n\t\td.logger.With(\"task_name\", handle.Config.Name, \"alloc_id\", handle.Config.AllocID),\n\t\td.nomadConfig.Topology.Compute(),\n\t)\n\tif err != nil {\n\t\td.logger.Error(\"failed to reattach to executor\", \"error\", err, \"task_id\", handle.Config.ID)\n\t\treturn fmt.Errorf(\"failed to reattach to executor: %v\", err)\n\t}\n\n\t// Try to restore monitor socket path.\n\ttaskDir := filepath.Join(handle.Config.AllocDir, handle.Config.Name)\n\tpossiblePaths := []string{\n\t\tfilepath.Join(taskDir, qemuMonitorSocketName),\n\t\t// Support restoring tasks that used the old socket name.\n\t\tfilepath.Join(taskDir, \"qemu-monitor.sock\"),","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/drivers/qemu/driver.go#L291-L327","documentation":"After decoding TaskState, RecoverTask converts the stored ReattachConfig into a go-plugin reattach config via pstructs.ReattachConfigToGoPlugin. If the stored reattach data is invalid (nil protocol, bad addr/pid fields), this wrapped error is returned.","triggerScenarios":"TaskState.ReattachConfig missing required fields (Pid, Protocol, Addr) or containing values that ReattachConfigToGoPlugin rejects during RecoverTask.","commonSituations":"Executor plugin died and left partial/invalid state; state persisted from an incompatible Nomad version with a different ReattachConfig shape.","solutions":["Confirm the executor process is still alive and its recorded PID/ReattachConfig are valid; if not, reschedule the allocation.","Upgrade/downgrade to matching Nomad versions so the ReattachConfig schema matches what was persisted.","Inspect the inner error in the message for which reattach field failed conversion."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := d.RecoverTask(handle)\nif err != nil && strings.Contains(err.Error(), \"failed to build ReattachConfig\") {\n    // reattach data is invalid; give up recovery and reschedule\n    return reschedule(allocID)\n}","preventionTips":["Verify the executor plugin is alive before attempting recovery.","Match Nomad versions between the client that wrote the state and the one recovering it."],"tags":["nomad","qemu-driver","go-plugin","reattach","recover-task"],"backgroundTag":"reattach-config-invalid","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"}