hashicorp/nomad · error
server_join and start_join cannot both be defined; prefer se
Error message
server_join and start_join cannot both be defined; prefer setting the server_join block
What it means
Nomad agents act as Consul servers; startup join can be configured either via the legacy top-level `start_join` list or the newer `server_join` block. This error is thrown during agent startup when both are set, because merging them would be ambiguous.
Source
Thrown at command/agent/command.go:1434
}
return inm, nil
}
func (c *Command) startupJoin(config *Config) error {
// Nothing to do
if !config.Server.Enabled {
return nil
}
// Validate both old and new aren't being set
old := len(config.Server.StartJoin)
var new int
if config.Server.ServerJoin != nil {
new = len(config.Server.ServerJoin.StartJoin)
}
if old != 0 && new != 0 {
return fmt.Errorf("server_join and start_join cannot both be defined; prefer setting the server_join block")
}
// Nothing to do
if old+new == 0 {
return nil
}
// Combine the lists and join
joining := config.Server.StartJoin
if new != 0 {
joining = append(joining, config.Server.ServerJoin.StartJoin...)
}
c.Ui.Output("Joining cluster...")
n, err := c.agent.server.Join(joining)
if err != nil {
return err
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Remove the legacy `start_join` list from the server config and keep only the `server_join` block (preferred).
- Or, if staying on legacy config, remove the `server_join` block so only `start_join` remains.
- Search all config files passed via -config (including directories) for duplicates of the two keys.
Example fix
// before
server {
start_join = ["10.0.0.5", "10.0.0.6"]
server_join { start_join = ["10.0.0.5"] }
}
// after
server {
server_join { start_join = ["10.0.0.5", "10.0.0.6"] }
} Defensive patterns
Strategy: validation
Validate before calling
func validateServerJoin(cfg *ServerConfig) error {
if len(cfg.StartJoin) > 0 && cfg.ServerJoin != nil && len(cfg.ServerJoin.StartJoin) > 0 {
return errors.New("only one of start_join or server_join.start_join may be set")
}
return nil
} Prevention
- Prefer the server_join block in all new configs
- Grep config templates for start_join when upgrading Nomad
- Validate agent config in CI with `nomad agent -config ... -verify-only`
When it happens
Trigger: Server config defines non-empty `server.start_join` AND a non-nil `server.server_join` block with non-empty `server_join.start_join`. Detected in startupJoin at agent startup (called from Run).
Common situations: Migrating config to the newer `server_join` block but forgetting to delete the old `start_join` key; merging agent config files or base/hcl overlays that each define one of the two; copy-pasting example configs from different Nomad versions.
Related errors
- Failed to initialize Consul client: %v
- no such consul cluster: %s
- must have at least client or server mode enabled
- failed to set up TLS expiration metrics: %w
- server_service_name must be set when auto_advertise is enabl
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/0cf87919d5cd8c9e.
Report an issue: GitHub.