{"record":{"id":"63a08d9232fbdd95","repo":"hashicorp/nomad","slug":"disconnect-cannot-be-configured-with-both-lost-aft","errorCode":null,"errorMessage":"Disconnect cannot be configured with both lost_after and stop_after","messagePattern":"Disconnect cannot be configured with both lost_after and stop_after","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/group.go","lineNumber":26,"sourceCode":"\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/hashicorp/go-multierror\"\n)\n\nconst (\n\t// ReconcileOption is used to specify the behavior of the reconciliation process\n\t// between the original allocations and the replacements when a previously\n\t// disconnected client comes back online.\n\tReconcileOptionKeepOriginal    = \"keep_original\"\n\tReconcileOptionKeepReplacement = \"keep_replacement\"\n\tReconcileOptionBestScore       = \"best_score\"\n\tReconcileOptionLongestRunning  = \"longest_running\"\n)\n\nvar (\n\t// Disconnect strategy validation errors\n\terrStopAndLost         = errors.New(\"Disconnect cannot be configured with both lost_after and stop_after\")\n\terrNegativeLostAfter   = errors.New(\"lost_after cannot be a negative duration\")\n\terrNegativeStopAfter   = errors.New(\"stop_after cannot be a negative duration\")\n\terrStopAfterNonService = errors.New(\"stop_after can only be used with service or batch job types\")\n\terrInvalidReconcile    = errors.New(\"reconcile option is invalid\")\n)\n\nfunc NewDefaultDisconnectStrategy() *DisconnectStrategy {\n\treturn &DisconnectStrategy{\n\t\tReplace:   new(true),\n\t\tReconcile: ReconcileOptionBestScore,\n\t}\n}\n\n// Disconnect strategy defines how both clients and server should behave in case of\n// disconnection between them.\ntype DisconnectStrategy struct {\n\t// Defines for how long the server will consider the unresponsive node as\n\t// disconnected but alive instead of lost.","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/group.go#L8-L44","documentation":"errStopAndLost is a job-validation error raised when a disconnect strategy configures both lost_after and stop_after. These fields are mutually exclusive: lost_after reconciles a disconnected client as 'lost', while stop_after stops the allocation — specifying both is ambiguous, so Validate rejects the job spec.","triggerScenarios":"Submitting a job (Job.Validate / job register or plan) whose group's disconnect block sets both lost_after (> 0) and stop_after (non-nil), checked at group.go:88 in DisconnectStrategy.Validate.","commonSituations":"Merging HCL/JSON fragments where one file sets lost_after and another sets stop_after; upgrading a job spec written for an older Nomad (only lost_after existed) and adding stop_after without removing lost_after; copy-paste of example disconnect configs.","solutions":["Remove either lost_after or stop_after from the disconnect block, keeping the behavior you want","If the desired behavior is 'reconcile as lost', set only lost_after and delete stop_after","If the desired behavior is 'stop the task', set only stop_after and delete lost_after","Run 'nomad job validate <file>' before submitting to catch the conflict early"],"exampleFix":"// before\ndisconnect {\n  lost_after  = \"2h\"\n  stop_after  = \"30m\"\n}\n// after\ndisconnect {\n  stop_after = \"30m\"\n}","handlingStrategy":"validation","validationCode":"if ds := grp.Disconnect; ds != nil && ds.LostAfter > 0 && ds.StopOnClientAfter != nil {\n    return fmt.Errorf(\"disconnect: set only one of lost_after or stop_after\")\n}","typeGuard":"func hasConflictingDisconnect(ds *api.DisconnectStrategy) bool {\n    return ds != nil && ds.LostAfter > 0 && ds.StopOnClientAfter != nil\n}","tryCatchPattern":"err := client.Jobs().Validate(job, nil, nil)\nif err != nil && strings.Contains(err.Error(), \"both lost_after and stop_after\") {\n    return fmt.Errorf(\"fix job spec: remove either lost_after or stop_after: %w\", err)\n}","preventionTips":["Keep only one of lost_after/stop_after in the disconnect block","Run 'nomad job validate' in CI before submitting job specs","When merging job-spec fragments, audit the disconnect block for duplicates","Prefer stop_after (newer field) and remove legacy lost_after if the new behavior is wanted"],"tags":["nomad","job-spec","validation","disconnect"],"backgroundTag":"conflicting-config-fields","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"}