hashicorp/nomad · error
server_join and retry_join cannot both be defined; prefer se
Error message
server_join and retry_join cannot both be defined; prefer setting the server_join block
What it means
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.
Source
Thrown at command/agent/retry_join.go:129
joinCfg *ServerJoin
// joinFunc is the function which executes the join process and is dependent
// on the agent mode.
joinFunc func([]string) (int, error)
// logger is the retry joiners logger
logger log.Logger
}
// Validate ensures that the configuration passes validity checks for the
// retry_join block. If the configuration is not valid, returns an error that
// will be displayed to the operator, otherwise nil.
func (r *retryJoiner) Validate(config *Config) error {
// If retry_join is defined for the server, ensure that deprecated
// fields and the server_join block are not both set
if config.Server != nil && config.Server.ServerJoin != nil && len(config.Server.ServerJoin.RetryJoin) != 0 {
if len(config.Server.RetryJoin) != 0 {
return fmt.Errorf("server_join and retry_join cannot both be defined; prefer setting the server_join block")
}
if len(config.Server.StartJoin) != 0 {
return fmt.Errorf("server_join and start_join cannot both be defined; prefer setting the server_join block")
}
if config.Server.RetryMaxAttempts != 0 {
return fmt.Errorf("server_join and retry_max cannot both be defined; prefer setting the server_join block")
}
if config.Server.RetryInterval != 0 {
return fmt.Errorf("server_join and retry_interval cannot both be defined; prefer setting the server_join block")
}
if len(config.Server.ServerJoin.StartJoin) != 0 {
return fmt.Errorf("retry_join and start_join cannot both be defined")
}
}
// if retry_join is defined for the client, ensure that start_join is notView on GitHub (pinned to 482b49bf1a)
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
Example fix
// before
server {
retry_join = ["1.2.3.4"]
server_join {
retry_join = ["1.2.3.4"]
}
}
// after
server {
server_join {
retry_join = ["1.2.3.4"]
}
} Defensive patterns
Strategy: validation
Validate before calling
if s := cfg.Server; s != nil && s.ServerJoin != nil && len(s.ServerJoin.RetryJoin) > 0 && len(s.RetryJoin) > 0 {
return errors.New("server_join.retry_join and server.retry_join are mutually exclusive")
} Try / catch
if err := agent.ValidateConfig(cfg); err != nil {
if strings.Contains(err.Error(), "cannot both be defined") {
// fix config, do not retry
return fmt.Errorf("config error: %w", err)
}
return err
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- server_join and start_join cannot both be defined; prefer se
- server_join and retry_max cannot both be defined; prefer set
- server_join and retry_interval cannot both be defined; prefe
- Reschedule policy has unlimited attempts enabled and a low d
- Lock delay and TTL must be positive
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/aaec97a79b996e98.
Report an issue: GitHub.