{"record":{"id":"6e30c27a9595b7d7","repo":"hashicorp/nomad","slug":"multiple-service-providers-used-task-group-servic","errorCode":null,"errorMessage":"Multiple service providers used: task group services must use the same provider","messagePattern":"Multiple service providers used: task group services must use the same provider","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"nomad/structs/structs.go","lineNumber":7579,"sourceCode":"\t\t\t\tidDuplicateSet.StringFunc(\n\t\t\t\t\tfunc(u unique) string {\n\t\t\t\t\t\ts := u.task + \"->\" + u.name\n\t\t\t\t\t\tif u.port != \"\" {\n\t\t\t\t\t\t\ts += \":\" + u.port\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn s\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t),\n\t\t)\n\t}\n\n\t// The initial feature release of native service discovery only allows for\n\t// a single service provider to be used across all services in a task\n\t// group.\n\tif providerSet.Size() > 1 {\n\t\tmErr.Errors = append(mErr.Errors,\n\t\t\terrors.New(\"Multiple service providers used: task group services must use the same provider\"))\n\t}\n\n\treturn mErr.ErrorOrNil()\n}\n\n// validateScriptChecksInGroupServices ensures group-level services with script\n// checks know what task driver to use. Either the service.task or service.check.task\n// parameter must be configured.\nfunc (tg *TaskGroup) validateScriptChecksInGroupServices() error {\n\tvar mErr multierror.Error\n\tfor _, service := range tg.Services {\n\t\tif service.TaskName == \"\" {\n\t\t\tfor _, check := range service.Checks {\n\t\t\t\tif check.Type == \"script\" && check.TaskName == \"\" {\n\t\t\t\t\tmErr.Errors = append(mErr.Errors,\n\t\t\t\t\t\tfmt.Errorf(\"Service [%s]->%s or Check %s must specify task parameter\",\n\t\t\t\t\t\t\ttg.Name, service.Name, check.Name,\n\t\t\t\t\t\t))","sourceCodeStart":7561,"sourceCodeEnd":7597,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L7561-L7597","documentation":"MaxClientDisconnect is deprecated in favor of the newer Disconnect block (Disconnect.LostAfter). Setting it on a task group now produces this validation error/warning so specs migrate to the replacement field.","triggerScenarios":"Submitting a job whose group still specifies max_client_disconnect after upgrading to a Nomad version that introduced Disconnect.LostAfter.","commonSituations":"Old job specs carried forward across a Nomad upgrade; templates or tooling still emitting the deprecated field; docs/examples written pre-1.7.","solutions":["Remove max_client_disconnect and add a disconnect { lost_after = \"...\" } block to the group.","Update tooling/templates that emit the deprecated field.","Check the Nomad version's deprecation notes for the exact replacement semantics."],"exampleFix":"// before\ngroup \"web\" {\n  max_client_disconnect = \"5m\"\n}\n// after\ngroup \"web\" {\n  disconnect {\n    lost_after = \"5m\"\n  }\n}","handlingStrategy":"validation","validationCode":"if tg.MaxClientDisconnect != nil {\n    return errors.New(\"max_client_disconnect is deprecated; use disconnect { lost_after = ... }\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Migrate specs to the Disconnect block when upgrading Nomad","Grep job repositories for deprecated fields after upgrades","Keep templates/tooling in sync with current Nomad API"],"tags":["nomad","deprecation","config-migration"],"backgroundTag":"deprecated-field-usage","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"}