{"record":{"id":"d711cdf97122a438","repo":"hashicorp/nomad","slug":"service-address-mode-must-be-q-if-address-is-set","errorCode":null,"errorMessage":"Service address_mode must be %q if address is set","messagePattern":"Service address_mode must be %q if address is set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/services.go","lineNumber":778,"sourceCode":"// Validate checks if the Service definition is valid\nfunc (s *Service) Validate() error {\n\tvar mErr multierror.Error\n\n\t// Ensure the service name is valid per the below RFCs but make an exception\n\t// for our interpolation syntax by first stripping any environment variables from the name\n\n\tserviceNameStripped := args.ReplaceEnvWithPlaceHolder(s.Name, \"ENV-VAR\")\n\n\tif err := s.ValidateName(serviceNameStripped); err != nil {\n\t\t// Log actual service name, not the stripped version.\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"%v: %q\", err, s.Name))\n\t}\n\n\tswitch s.AddressMode {\n\tcase \"\", AddressModeAuto:\n\tcase AddressModeHost, AddressModeDriver, AddressModeAlloc, AddressModeAllocIPv6:\n\t\tif s.Address != \"\" {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Service address_mode must be %q if address is set\", AddressModeAuto))\n\t\t}\n\tdefault:\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Service address_mode must be %q, %q, or %q; not %q\", AddressModeAuto, AddressModeHost, AddressModeDriver, s.AddressMode))\n\t}\n\n\tswitch s.OnUpdate {\n\tcase \"\", OnUpdateIgnore, OnUpdateRequireHealthy, OnUpdateIgnoreWarn:\n\t\t// OK\n\tdefault:\n\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Service on_update must be %q, %q, or %q; not %q\", OnUpdateRequireHealthy, OnUpdateIgnoreWarn, OnUpdateIgnore, s.OnUpdate))\n\t}\n\n\t// Up until this point, all service validation has been independent of the\n\t// provider. From this point on, we have different validation paths. We can\n\t// also catch an incorrect provider parameter.\n\tswitch s.Provider {\n\tcase ServiceProviderConsul:\n\t\ts.validateConsulService(&mErr)","sourceCodeStart":760,"sourceCodeEnd":796,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/services.go#L760-L796","documentation":"In Service.Validate, an explicit service Address was set while AddressMode was one of host/driver/alloc/alloc_ipv6. A static address is only meaningful in auto mode, where Nomad substitutes the interpolated address into the service registration.","triggerScenarios":"Setting both Service.Address (non-empty) and Service.AddressMode to host, driver, alloc, or alloc_ipv6, then validating.","commonSituations":"Migrating configs from host-address style to address_mode without removing the address field; generators emitting both fields.","solutions":["Remove the address field and rely on address_mode","Set address_mode to \"auto\" (or omit it) when address is specified"],"exampleFix":"// before\naddress_mode = \"host\"\naddress = \"10.0.0.5\"\n// after\naddress_mode = \"auto\"\naddress = \"10.0.0.5\"","handlingStrategy":"validation","validationCode":"if s.Address != \"\" && s.AddressMode != \"\" && s.AddressMode != structs.AddressModeAuto {\n    return fmt.Errorf(\"address must use address_mode=auto\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never combine explicit address with a non-auto address_mode","Pick one addressing style per service"],"tags":["nomad","address-mode","validation"],"backgroundTag":"invalid-service-network-config","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"}