Skip to content

Substrate readiness — capability gaps that stop the cluster serving.

GET
/v1/admin/substrate/readiness
Code sample: Shell / cURL
curl --request GET \
--url https://stratum.example.com/v1/admin/substrate/readiness \
--header 'Authorization: Bearer <token>'

Bootstrap-admin endpoint reporting what this cluster cannot currently do, as distinct from what is broken.

A cluster can be entirely healthy — every service green, every node up and still be unable to create an instance, because a required Day-2 step has not been completed. The most common case is storage: on a Ceph-only install the installer deliberately provisions no local LVM and seeds no storage classes, because pools and classes are an operator action after the Ceph cluster is formed. That is correct behaviour and it means a brand-new cluster has no usable storage until someone finishes the job.

Without this endpoint that state is invisible until the first instance create fails, with an error at the point of use rather than a hint on the substrate page.

Findings are derived from CURRENT state on every request — never accumulated — so one clears as soon as its condition is resolved.

ready is false only when a blocking finding is present. Warnings do not make a working cluster report itself unusable.

Faults belong elsewhere: a service that is down appears in /v1/admin/substrate/services, and a metric out of range raises a health alarm..

Readiness report for the cluster.

Media typeapplication/json
object
ready
required

False when any CORE finding (one with no service) is blocking, i.e. a core operation cannot be performed at all. Warnings do not clear this flag, and neither does a service-scoped finding: “ready for instances, not for S3” is reported in services.

boolean
findings
required

Capability gaps, most severe first and stable within a severity so a polling UI does not reshuffle the list.

Array<object>
object
code
required

Stable identifier for the kind of gap. Clients key off this for icons and deep links, and operators may script against it.

string
Allowed values: NoStorageClass StorageAwaitsCeph NoDefaultStorageClass StorageClassBackendUnavailable NoImages ObjectStorageNotDeployed ObjectStorageAwaitsCeph ServiceEndpointImpaired OperatorRecipeNeverBuilt CatalogImportFailing NoAlertChannel NodeNotReporting ObsStackDown TimeNotSynced TimeSourceLocalClock PatroniNoSinglePrimary MgmtBridgeNoFirewallZone SubstrateGuardNotApplied SubstrateGuardDisabled DataplanePinOverridden NodeDataplaneImageDrift NodeDataplaneImagesUnreported AlertSendFailing AlertNotifyFailing AlertDeliveryUnobserved ClusterCAExpiring AdminPasswordDefault CephHealthNotOK CephCrashUnacknowledged ImageNodeStagingStale ImageBuilderNoSubnet EvacuationNotArmed NoReapModeOn AcmeOrdersWithoutIssuer FrontDoorMissing FrontDoorNamesUnpublished PackAlarmMissing QuotaDefaultsMissing QuotaOverLimit ClusterShutdown NodePowerAction UpgradeInProgress UpgradeFailed NodeRolledBack UpdateAvailable SecurityUpdateAvailable UpdateCheckFailed NodeRebootPending HostBinariesStale SingleInstallAdmin UnderlayRoleMismatch BondDegraded DataplaneDBRoleUnusable DataplaneDBRoleUnreported DataplaneDBRoleSwitchPending DataplaneDBRoleNotConnected LBConfigFilePending RecursorConfigFilePending SubstrateNearReservation NodeCommittedOverAllocatable DevModeOn OpenBaoUnsealKeyOnDisk OpenBaoRootToken OpenBaoTokenExpiring OpenBaoTokenRenewalFailing OpenBaoPoliciesStale CephadmMissing CephadmVersionMismatch CephBootstrapFailed StoragePathMTU OverlayPathMTU MembershipLagging MembershipJoinFailed FormationNoFaultTolerance FormationBelowPlannedSize JoinCodeLiveAtPlannedSize OVNCentralDown ProviderTopologyDisagrees ProviderUplinkMissing OVNRemoteIncomplete GatewayChassisUnderspread ProviderTransitOffProviderNetwork ProviderGatewayVIPDisagrees BackupsOff
severity
required

blocking — a core operation cannot be performed at all. warning — it works, but a foreseeable case will fail. info — nothing is wrong: a deliberate state worth knowing about, such as a node installed offline keeping time on its own clock (TimeSourceLocalClock). Clients should not render it as a problem.

string
Allowed values: blocking warning info
title
required

One-line statement of what is missing.

string
detail
required

What this prevents, phrased in terms of what the operator was trying to do rather than the internal object that is absent. May span several lines (the path-MTU findings list each failing path on its own line).

string
remediation
required

The next action to take. Every finding carries one — a finding without a remediation is just a complaint.

string
subject

The specific object involved (e.g. a storage class name), when the finding is about one. Absent for cluster-wide gaps.

string
service

The service the finding is about (s3, db, k8s, a service endpoint’s key),. Absent for a core finding, which affects the cluster’s ability to run anything. A service-scoped blocking finding makes that service not ready (see services) without making the cluster not ready.

string
waitsFor

The code of the core finding that has to be resolved before this one can be acted on at all, e.g. StorageAwaitsCeph on an operator recipe that cannot be built before the cluster has a storage class. The finding still counts (its service is not ready); the service-not-ready alarm leaves it out. Absent when it can be acted on now.

string
fix

The single API call that resolves the finding, when one exists.

object
method
required
string
path
required
string
pathMtu

The facts of a StoragePathMTU or OverlayPathMTU finding in machine form, for a console to draw its table and its fix button from.

object
network
required
string
Allowed values: storage overlay
mtu
required

The MTU the network is set to, as the failing interfaces run it.

integer
carriedMtu

The least any failing path carries. Absent when a path has not been measured (the host-helper measures only a path that failed, and not more often than every few minutes).

integer
paths
required

The failing paths, one per sender and peer.

Array<object>
object
from
required

The sending node’s id.

string
fromName

Its name, when it has one.

string
to
required

The peer’s node id.

string
toName
string
address

The peer’s address on the network.

string
interface

The sending interface.

string
mtu
required

The sending interface’s MTU.

integer
carriedMtu

What the path carries. Absent when not measured.

integer
fix

The way out the platform can do itself: lower the network’s MTU to what every failing path carries, with PUT /v1/admin/cluster/networks/{network}/mtu and {"mtu": mtu}. Absent when it is not offered (see noFixReason): the path has to be raised.

object
action
required
string
Allowed values: set-network-mtu
network
required
string
Allowed values: storage overlay
mtu
required

What to set, the least any failing path carries.

integer
minMtu
required

The lowest MTU offered for the network (overlay 1558, storage 1500).

integer
noFixReason

Why no fix is offered. Absent when fix is present.

string
services

Per-service rollup of the service-scoped findings: a service is not ready when any of its findings is blocking. Services with no findings are absent, except a service that is switched off or not on this install profile: it is listed with disabled: true, no findings, and ready: true (nothing blocks it, it is off on purpose). A console shows it as off, not as a gap.

object
key
additional properties
object
ready
required
boolean
findings
required

The codes of the service’s findings, most severe first.

Array<string>
disabled

The service is switched off or not on this install profile.

boolean
reason

Why a disabled service is off.

string
blocking

What keeps the service not ready: one entry per blocking finding code, with the subjects it was raised for (e.g. the recipe names). The CLI’s service line and the installer report’s serviceBlocking show exactly this. Absent when ready.

Array<object>
object
code
required
string
subjects
required
Array<string>
incomplete

Checks whose input could not be read on this evaluation. Their findings are absent because they are unknown, not because the condition is fine; a short list with entries here is not a clean bill of health.

Array<string>
settling

The cluster’s first convergence after install. From the control plane’s first start until every substrate service and every reconciler expected on this install has reported a first healthy pass, or until deadline, the cluster is settling: warning findings move to held and firing alerts are held in the admin alert list. A console shows “Starting” with ready of total instead of errors while the phase is settling.

An upgrade starts it again from its last restart or reboot (reason: upgrade).

Derived from current state on every request; nothing is stored. After the deadline the phase is ready or degraded from the same inputs.

object
phase
required

settling: not everything has converged and the deadline has not passed. ready: every item has converged. degraded: the deadline passed and something has not converged; pending names it.

string
Allowed values: settling ready degraded
ready
required

Items that have converged.

integer
total
required

Items expected on this install.

integer
pending
required

The items not converged yet, services first, then reconcilers.

Array<object>

One substrate service on one node, or one reconciler, that has not converged.

object
kind
required
string
Allowed values: service reconciler
name
required
string
node

The node, for a service.

string
health
required

The item’s current health in its own vocabulary: a service’s healthy|unhealthy|unknown, a reconciler’s fleet health (never_ran, failed, unknown,…).

string
since
required

The control plane’s first start on this cluster, or the last restart or reboot an upgrade caused when that is later.

string format: date-time
deadline
required

When settling ends whether or not everything converged.

string format: date-time
reason

Why the cluster settles from since.

string
Allowed values: install upgrade
incomplete

Inputs that could not be read. The phase is never ready while one is missing.

Array<string>
held

Warning findings raised while the cluster settles (settling.phase is settling). They are not in findings, and do not count in services. Findings are recomputed on every request, so one still present when settling ends moves back to findings. Blocking findings are never held. A console shows these, if at all, as part of the startup progress rather than as problems.

Array<object>
object
code
required

Stable identifier for the kind of gap. Clients key off this for icons and deep links, and operators may script against it.

string
Allowed values: NoStorageClass StorageAwaitsCeph NoDefaultStorageClass StorageClassBackendUnavailable NoImages ObjectStorageNotDeployed ObjectStorageAwaitsCeph ServiceEndpointImpaired OperatorRecipeNeverBuilt CatalogImportFailing NoAlertChannel NodeNotReporting ObsStackDown TimeNotSynced TimeSourceLocalClock PatroniNoSinglePrimary MgmtBridgeNoFirewallZone SubstrateGuardNotApplied SubstrateGuardDisabled DataplanePinOverridden NodeDataplaneImageDrift NodeDataplaneImagesUnreported AlertSendFailing AlertNotifyFailing AlertDeliveryUnobserved ClusterCAExpiring AdminPasswordDefault CephHealthNotOK CephCrashUnacknowledged ImageNodeStagingStale ImageBuilderNoSubnet EvacuationNotArmed NoReapModeOn AcmeOrdersWithoutIssuer FrontDoorMissing FrontDoorNamesUnpublished PackAlarmMissing QuotaDefaultsMissing QuotaOverLimit ClusterShutdown NodePowerAction UpgradeInProgress UpgradeFailed NodeRolledBack UpdateAvailable SecurityUpdateAvailable UpdateCheckFailed NodeRebootPending HostBinariesStale SingleInstallAdmin UnderlayRoleMismatch BondDegraded DataplaneDBRoleUnusable DataplaneDBRoleUnreported DataplaneDBRoleSwitchPending DataplaneDBRoleNotConnected LBConfigFilePending RecursorConfigFilePending SubstrateNearReservation NodeCommittedOverAllocatable DevModeOn OpenBaoUnsealKeyOnDisk OpenBaoRootToken OpenBaoTokenExpiring OpenBaoTokenRenewalFailing OpenBaoPoliciesStale CephadmMissing CephadmVersionMismatch CephBootstrapFailed StoragePathMTU OverlayPathMTU MembershipLagging MembershipJoinFailed FormationNoFaultTolerance FormationBelowPlannedSize JoinCodeLiveAtPlannedSize OVNCentralDown ProviderTopologyDisagrees ProviderUplinkMissing OVNRemoteIncomplete GatewayChassisUnderspread ProviderTransitOffProviderNetwork ProviderGatewayVIPDisagrees BackupsOff
severity
required

blocking — a core operation cannot be performed at all. warning — it works, but a foreseeable case will fail. info — nothing is wrong: a deliberate state worth knowing about, such as a node installed offline keeping time on its own clock (TimeSourceLocalClock). Clients should not render it as a problem.

string
Allowed values: blocking warning info
title
required

One-line statement of what is missing.

string
detail
required

What this prevents, phrased in terms of what the operator was trying to do rather than the internal object that is absent. May span several lines (the path-MTU findings list each failing path on its own line).

string
remediation
required

The next action to take. Every finding carries one — a finding without a remediation is just a complaint.

string
subject

The specific object involved (e.g. a storage class name), when the finding is about one. Absent for cluster-wide gaps.

string
service

The service the finding is about (s3, db, k8s, a service endpoint’s key),. Absent for a core finding, which affects the cluster’s ability to run anything. A service-scoped blocking finding makes that service not ready (see services) without making the cluster not ready.

string
waitsFor

The code of the core finding that has to be resolved before this one can be acted on at all, e.g. StorageAwaitsCeph on an operator recipe that cannot be built before the cluster has a storage class. The finding still counts (its service is not ready); the service-not-ready alarm leaves it out. Absent when it can be acted on now.

string
fix

The single API call that resolves the finding, when one exists.

object
method
required
string
path
required
string
pathMtu

The facts of a StoragePathMTU or OverlayPathMTU finding in machine form, for a console to draw its table and its fix button from.

object
network
required
string
Allowed values: storage overlay
mtu
required

The MTU the network is set to, as the failing interfaces run it.

integer
carriedMtu

The least any failing path carries. Absent when a path has not been measured (the host-helper measures only a path that failed, and not more often than every few minutes).

integer
paths
required

The failing paths, one per sender and peer.

Array<object>
object
from
required

The sending node’s id.

string
fromName

Its name, when it has one.

string
to
required

The peer’s node id.

string
toName
string
address

The peer’s address on the network.

string
interface

The sending interface.

string
mtu
required

The sending interface’s MTU.

integer
carriedMtu

What the path carries. Absent when not measured.

integer
fix

The way out the platform can do itself: lower the network’s MTU to what every failing path carries, with PUT /v1/admin/cluster/networks/{network}/mtu and {"mtu": mtu}. Absent when it is not offered (see noFixReason): the path has to be raised.

object
action
required
string
Allowed values: set-network-mtu
network
required
string
Allowed values: storage overlay
mtu
required

What to set, the least any failing path carries.

integer
minMtu
required

The lowest MTU offered for the network (overlay 1558, storage 1500).

integer
noFixReason

Why no fix is offered. Absent when fix is present.

string

Example

{
"findings": [
{
"code": "NoStorageClass",
"severity": "blocking",
"title": "No storage class is defined",
"subject": "replicated",
"service": "s3",
"waitsFor": "StorageAwaitsCeph",
"fix": {
"method": "POST",
"path": "/v1/admin/storage/ceph/rgw"
},
"pathMtu": {
"network": "storage",
"mtu": 9000,
"carriedMtu": 1500,
"paths": [
{
"address": "192.0.2.112",
"interface": "vlan90"
}
],
"fix": {
"action": "set-network-mtu",
"network": "storage",
"mtu": 1500
}
}
}
],
"settling": {
"phase": "settling",
"pending": [
{
"kind": "service"
}
],
"reason": "install"
},
"held": [
{
"code": "NoStorageClass",
"severity": "blocking",
"title": "No storage class is defined",
"subject": "replicated",
"service": "s3",
"waitsFor": "StorageAwaitsCeph",
"fix": {
"method": "POST",
"path": "/v1/admin/storage/ceph/rgw"
},
"pathMtu": {
"network": "storage",
"mtu": 9000,
"carriedMtu": 1500,
"paths": [
{
"address": "192.0.2.112",
"interface": "vlan90"
}
],
"fix": {
"action": "set-network-mtu",
"network": "storage",
"mtu": 1500
}
}
}
]
}

Authenticated but not authorized.

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
>= 400 <= 599
detail
string
instance
string format: uri-reference
requestId
required
string
code
required
string
issues

The findings of a rejected IAM policy document (custom and resource policies).

Array<object>

One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.

object
code
required

The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.

string
statement
required

Index of the statement at fault; -1 for the document as a whole.

integer
>= -1
detail
required
string
action

The offending action, where one is at fault (ACTION_NOT_APPLICABLE).

string
errors

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.

Array<object>

One field’s problem, the stage-2 installer API’s shape. field is the field’s path, message what is wrong with it.

object
field
required

The field’s path, e.g. links[0].interface, disks[1].confirm, mgmt.address or role; empty for the whole request.

string
message
required
string
details

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
key
additional properties
any

Example

{
"issues": [
{
"code": "ACTION_NOT_APPLICABLE",
"action": "compute:CreateVpc"
}
]
}