hashicorp/nomad · error

failed joining: %s

Error message

failed joining: %s

What it means

Agent.Join() in api/agent.go issues a PUT to /v1/agent/join; if the HTTP request itself fails, the error is wrapped as "failed joining: %s" (this index is the client-error branch). It signals the join RPC never completed successfully at the transport/API level.

Source

Thrown at api/agent.go:140

}

// Join is used to instruct a server node to join another server
// via the gossip protocol. Multiple addresses may be specified.
// We attempt to join all the hosts in the list. Returns the
// number of nodes successfully joined and any error. If one or
// more nodes have a successful result, no error is returned.
func (a *Agent) Join(addrs ...string) (int, error) {
	// Accumulate the addresses
	v := url.Values{}
	for _, addr := range addrs {
		v.Add("address", addr)
	}

	// Send the join request
	var resp joinResponse
	_, err := a.client.put("/v1/agent/join?"+v.Encode(), nil, &resp, nil)
	if err != nil {
		return 0, fmt.Errorf("failed joining: %s", err)
	}
	if resp.Error != "" {
		return 0, fmt.Errorf("failed joining: %s", resp.Error)
	}
	if resp.Warning != "" {
		return resp.NumJoined, errors.New(resp.Warning)
	}
	return resp.NumJoined, nil
}

// Members is used to query all of the known server members
func (a *Agent) Members() (*ServerMembers, error) {
	var resp *ServerMembers

	// Query the known members
	_, err := a.client.query("/v1/agent/members", &resp, nil)
	if err != nil {
		return nil, err

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Inspect the wrapped error: fix connectivity (agent down/wrong port) or supply an ACL token with agent write permissions.
  2. Verify the join address is a reachable Consul agent and includes the correct port (8301 by default).
  3. Retry with correct `wan` boolean (false for LAN pool) and check agent logs for the join rejection reason.

Example fix

// before
_, err := agent.Join([]string{"10.0.0.5"}, true) // 403: no token
// after
client.SetToken(os.Getenv("CONSUL_HTTP_TOKEN"))
_, err := agent.Join([]string{"10.0.0.5:8301"}, false)
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure local agent API is up and token present before Join
if err := checkAgentHealth(client); err != nil {
    return fmt.Errorf("cannot join: local agent unavailable: %w", err)
}
if client.Token() == "" && aclsEnabled {
    return fmt.Errorf("join requires an ACL token with agent:write")
}

Try / catch

n, err := agent.Join(addrs, wan)
if err != nil {
    if strings.Contains(err.Error(), "failed joining") {
        return fmt.Errorf("join request failed, check ACL token/agent address: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling Agent.Join(addresses, wan) when the PUT fails — agent unreachable, 403 from ACLs, or the target address parameter is invalid enough that the agent rejects the request.

Common situations: Joining a cluster from automation where the local agent is down or the ACL token lacks `agent:write`; wrong WAN flag; DNS resolution failure for the join address.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/d982df51a76e76c7. Report an issue: GitHub.