Record that a node's join did not finish.
curl --request POST \ --url https://stratum.example.com/v1/admin/cluster/members/example/join-failed \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "step": "join/raft-openbao", "error": "example" }'. Moves a joining member to failed, with
the step it stopped in and the last error line. The membership generation
is bumped, so every member drops it from its peer lists, and the founder
side takes it back out of every raft it reached (OpenBao remove-peer, OVN
cluster/kick, Patroni member removal), so a failed join never leaves a
stale voter. raftCleanupAt is set when that is done.
A firstboot --config joiner calls this itself when a join step fails. An
operator calls it for a join that stalled.
Only a joining member moves; for any other state this returns the record
unchanged.
Gates on cluster:ReportJoinFailure.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”object
The join step that failed (a progress phase name).
Example
join/raft-openbaoThe last error line.
Responses
Section titled “Responses”The member record after the change.
A node’s cluster membership.
Membership is the cluster’s topology: every peer list a node renders
(Patroni, OpenBao and OVN raft peers, keepalived priorities, vmstorage
nodes, Alertmanager peers) is derived from the members in joining or
active, by a per-node reconciler, and every change bumps the membership
generation.
Membership also decides transport access: the node-transport listener refuses a peer that is not a member, even when its certificate is valid and cluster-signed. Decommissioning a node IS how you revoke it — there is no CRL.
Records are never deleted, only moved to decommissioned, so a refusal can
say who revoked the node, when, and why.
object
joining: admitted and installing (already in every peer list);
active; failed: a join that did not finish (out of every peer
list, taken back out of every raft it reached); removing;
decommissioned.
The node role.
The management address every peer list names.
Optional storage/overlay bindings, keyed by traffic class.
object
object
Declared labels; topology.rack is the rack.
object
The declared rack (labels["topology.rack"]).
Orders every peer list and the keepalived priorities (1 = the founder).
The membership generation this node reports it has rendered and applied (its own report). A member below the cluster’s generation is lagging.
The join step a failed member stopped in.
The last error line of that step.
When a failed member was taken back out of every raft it reached.
Why the node was decommissioned. Required when decommissioning.
Who decommissioned it — a user id, or stratum-installer for membership
the install declared.
Example
{ "nodeId": "n-msst0002", "state": "joining", "role": "hybrid", "mgmtIp": "192.0.2.12"}Bad request.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Authenticated but not authorized.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Resource not found.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
Field errors, for codes that carry them: each problem at its field
(see FieldError). Documented on the responses that set it, e.g.
approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED.
Absent otherwise.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
Structured facts about the refusal, for codes that carry them. The
shape is fixed per code and documented on the response that answers
it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and
IMAGE_IN_USE. Absent for codes that carry none.
object
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}