{"record":{"id":"26b56d6d0c50d5eb","repo":"hashicorp/nomad","slug":"unknown-service-registration-provider-for-update","errorCode":null,"errorMessage":"unknown service registration provider for update: %q","messagePattern":"unknown service registration provider for update: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/serviceregistration/wrapper/wrapper.go","lineNumber":123,"sourceCode":"\n\t// Hot path to exit if there is nothing to do.\n\tif len(old.Services) == 0 && len(new.Services) == 0 {\n\t\treturn nil\n\t}\n\n\tnewProvider := new.RegistrationProvider()\n\toldProvider := old.RegistrationProvider()\n\n\t// If the new and old services use the same provider, call the\n\t// UpdateWorkload and leave it at that.\n\tif newProvider == oldProvider {\n\t\tswitch newProvider {\n\t\tcase structs.ServiceProviderNomad:\n\t\t\treturn h.nomadServiceProvider.UpdateWorkload(old, new)\n\t\tcase structs.ServiceProviderConsul:\n\t\t\treturn h.consulServiceProvider.UpdateWorkload(old, new)\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unknown service registration provider for update: %q\", newProvider)\n\t\t}\n\t}\n\n\t// If we have new services, call the relevant provider. Registering can\n\t// return an error. Do this before RemoveWorkload, so we can halt the\n\t// process if needed, otherwise we may leave the task/group\n\t// registration-less.\n\tif len(new.Services) > 0 {\n\t\tif err := h.RegisterWorkload(new); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif len(old.Services) > 0 {\n\t\th.RemoveWorkload(old)\n\t}\n\n\treturn nil","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/serviceregistration/wrapper/wrapper.go#L105-L141","documentation":"When a service changes providers between the old and new registration (old provider != new provider), the wrapper first removes via the old provider, then registers via the new one, dispatching UpdateWorkload on the new provider. This error is returned when the NEW provider string is neither \"nomad\" nor \"consul\", so no backend can handle the update.","triggerScenarios":"UpdateWorkload detects oldProvider != newProvider and switches to the switch on newProvider; newProvider has an unrecognized value (empty string, typo, or provider from a newer Nomad version unknown to this client), raised from Update/preRunLocked paths.","commonSituations":"Editing a job to change provider but with a typo'd target value; job spec produced by tooling that emits an unsupported provider; version skew where a job built for a newer Nomad is applied to an older client.","solutions":["Correct the new provider value in the job to \"nomad\" or \"consul\"","Re-submit the job through validation so unknown providers are rejected before update","Align Nomad client version with the version that understands the provider in the spec"],"exampleFix":"// before\nservice {\n  name = \"web\"\n  provider = \"hashicorp\"\n}\n// after\nservice {\n  name = \"web\"\n  provider = \"nomad\"\n}","handlingStrategy":"validation","validationCode":"if newProvider != oldProvider && !knownProvider(newProvider) {\n    return fmt.Errorf(\"provider change %q -> %q rejected: target provider unknown\", oldProvider, newProvider)\n}","typeGuard":"func canHandleUpdate(oldP, newP string) bool {\n    return knownProvider(newP) && knownProvider(oldP)\n}","tryCatchPattern":"err := wrapper.UpdateWorkload(old, new)\nif err != nil && strings.Contains(err.Error(), \"unknown service registration provider for update\") {\n    logger.Error(\"provider switch to unknown backend\", \"old\", old.Provider, \"new\", new.Provider)\n    return err\n}","preventionTips":["When changing a service's provider, use only \"nomad\" or \"consul\" as the target","Validate edited jobs before apply so provider switches are checked upfront","Version-align clients with any tooling that emits provider fields"],"tags":["nomad","service-registration","invalid-enum","provider-update"],"backgroundTag":"unknown-provider","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"}