{"record":{"id":"aaec97a79b996e98","repo":"hashicorp/nomad","slug":"server-join-and-retry-join-cannot-both-be-defined","errorCode":null,"errorMessage":"server_join and retry_join cannot both be defined; prefer setting the server_join block","messagePattern":"server_join and retry_join cannot both be defined; prefer setting the server_join block","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/retry_join.go","lineNumber":129,"sourceCode":"\tjoinCfg *ServerJoin\n\n\t// joinFunc is the function which executes the join process and is dependent\n\t// on the agent mode.\n\tjoinFunc func([]string) (int, error)\n\n\t// logger is the retry joiners logger\n\tlogger log.Logger\n}\n\n// Validate ensures that the configuration passes validity checks for the\n// retry_join block. If the configuration is not valid, returns an error that\n// will be displayed to the operator, otherwise nil.\nfunc (r *retryJoiner) Validate(config *Config) error {\n\t// If retry_join is defined for the server, ensure that deprecated\n\t// fields and the server_join block are not both set\n\tif config.Server != nil && config.Server.ServerJoin != nil && len(config.Server.ServerJoin.RetryJoin) != 0 {\n\t\tif len(config.Server.RetryJoin) != 0 {\n\t\t\treturn fmt.Errorf(\"server_join and retry_join cannot both be defined; prefer setting the server_join block\")\n\t\t}\n\t\tif len(config.Server.StartJoin) != 0 {\n\t\t\treturn fmt.Errorf(\"server_join and start_join cannot both be defined; prefer setting the server_join block\")\n\t\t}\n\t\tif config.Server.RetryMaxAttempts != 0 {\n\t\t\treturn fmt.Errorf(\"server_join and retry_max cannot both be defined; prefer setting the server_join block\")\n\t\t}\n\n\t\tif config.Server.RetryInterval != 0 {\n\t\t\treturn fmt.Errorf(\"server_join and retry_interval cannot both be defined; prefer setting the server_join block\")\n\t\t}\n\n\t\tif len(config.Server.ServerJoin.StartJoin) != 0 {\n\t\t\treturn fmt.Errorf(\"retry_join and start_join cannot both be defined\")\n\t\t}\n\t}\n\n\t// if retry_join is defined for the client, ensure that start_join is not","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/retry_join.go#L111-L147","documentation":"Nomad's retryJoiner.Validate checks agent configuration consistency. The newer server_join block and the deprecated top-level retry_join field were both set for the server stanza, which is ambiguous; Nomad rejects the config and asks operators to prefer server_join.","triggerScenarios":"Agent config HCL/JSON where server { server_join { retry_join = [...] } } and server { retry_join = [...] } are both non-empty; Validate is called during agent startup config parsing (via handleRetryJoin).","commonSituations":"Upgrading from older Nomad versions (pre server_join) where retry_join was top-level, then adding a server_join block without removing the legacy key; copying example configs that mix old and new syntax.","solutions":["Remove the deprecated retry_join field from the server stanza, keeping only server_join { retry_join }","Migrate all related fields at once: start_join, retry_max, retry_interval also have server_join equivalents","Run 'nomad agent -config' validation (nomad config validate) after editing to catch remaining conflicts"],"exampleFix":"// before\nserver {\n  retry_join = [\"1.2.3.4\"]\n  server_join {\n    retry_join = [\"1.2.3.4\"]\n  }\n}\n// after\nserver {\n  server_join {\n    retry_join = [\"1.2.3.4\"]\n  }\n}","handlingStrategy":"validation","validationCode":"if s := cfg.Server; s != nil && s.ServerJoin != nil && len(s.ServerJoin.RetryJoin) > 0 && len(s.RetryJoin) > 0 {\n    return errors.New(\"server_join.retry_join and server.retry_join are mutually exclusive\")\n}","typeGuard":null,"tryCatchPattern":"if err := agent.ValidateConfig(cfg); err != nil {\n\tif strings.Contains(err.Error(), \"cannot both be defined\") {\n\t\t// fix config, do not retry\n\t\treturn fmt.Errorf(\"config error: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Use only the server_join block; avoid deprecated top-level retry_join","Run nomad config validate in CI for every config change","Grep templates for legacy keys (retry_join, start_join, retry_max, retry_interval) before upgrade","Migrate all deprecated join fields together, not piecemeal"],"tags":["nomad","configuration","validation","deprecated-fields"],"backgroundTag":"config-conflict","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"}