rustfs/rustfs · error · TierProbeIntentError
tier probe intent json error: {0}
Error message
tier probe intent json error: {0} What it means
TierProbeIntentError::Json wraps a serde_json::Error produced while serializing an intent (encode) or deserializing a persisted envelope/inner intent (decode). Because PersistedTierProbeIntent and TierProbeIntent use #[serde(deny_unknown_fields)] and tagged enums, this fires for malformed JSON, missing or unknown fields, and fields of the wrong type. It means the stored bytes are not a valid tier probe intent envelope under the strict schema.
Source
Thrown at crates/ecstore/src/services/tier/tier_probe_intent.rs:49
pub(crate) const MAX_TIER_PROBE_INTENT_SIZE: usize = 64 * 1024;
const TIER_PROBE_OBJECT_PREFIX: &str = "rustfs-tier-probe-";
pub(crate) type Result<T> = std::result::Result<T, TierProbeIntentError>;
#[derive(Debug, thiserror::Error)]
pub(crate) enum TierProbeIntentError {
#[error("tier probe intent is corrupt: {0}")]
Corrupt(&'static str),
#[error("tier probe intent schema is unsupported: {0}")]
UnsupportedSchema(String),
#[error("tier probe intent checksum mismatch")]
ChecksumMismatch,
#[error("invalid tier probe intent state change from {from:?} to {to:?}")]
InvalidStateChange {
from: TierProbeIntentState,
to: TierProbeIntentState,
},
#[error("tier probe intent json error: {0}")]
Json(#[from] serde_json::Error),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub(crate) enum TierProbeIntentState {
UploadOutcomeUnknown,
Uploaded,
CleanupPending,
AbortedNoRemote,
Completed,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub(crate) enum TierProbeRemoteVersionKind {
#[default]
Unknown,View on GitHub (pinned to 5dca076efe)
Solutions
- Read the wrapped serde_json message — it names the exact path, field, and reason (unknown field, missing field, invalid type).
- Remove unknown fields and restore all required fields with correct types, matching the deny_unknown_fields strict schema.
- If the record was hand-edited or written by foreign tooling, delete it and re-run the tier probe rather than patching JSON in place.
- If corruption is suspected rather than editing, heal the erasure set / restore from a quorum copy of the metadata object.
Example fix
// before: extra/misspelled fields rejected by deny_unknown_fields
{"schema":"rustfs-tier-probe-intent-v1","content_sha256":"...","intent":{...,"tier_namee":"COLD-A"}}
// after: strict, canonical envelope with only known fields
{"schema":"rustfs-tier-probe-intent-v1","content_sha256":"<sha256-of-intent-json>","intent":{"probe_id":"...","revision":1,"state":"upload_outcome_unknown",/* all required fields, exact names */}} Defensive patterns
Strategy: try-catch
Validate before calling
fn is_strict_envelope(data: &[u8]) -> bool {
serde_json::from_slice::<PersistedTierProbeIntent>(data).is_ok()
} Try / catch
match TierProbeIntent::decode(probe_id, &data) {
Ok(intent) => use_intent(intent),
Err(TierProbeIntentError::Json(e)) => {
tracing::warn!(error = %e, "tier probe intent envelope failed strict JSON parse");
delete_corrupt_record_and_reprobe(probe_id).await?;
}
Err(e) => return Err(e.into()),
} Prevention
- Never hand-edit intent record JSON: deny_unknown_fields rejects any extra or misspelled field.
- Serialize only through TierProbeIntent::encode so the canonical layout and checksum stay consistent.
- Keep all nodes and tooling on a RustFS version using the same serde schema.
- If repairing records, rewrite them via encode() rather than patching JSON text.
When it happens
Trigger: decode on bytes that are not valid JSON or whose envelope/intent has an unknown field (deny_unknown_fields), a missing required field (e.g. old_config_etag in an add operation identity), a wrongly typed field, or an invalid tag for the TierProbeOperationIdentity tagged enum; encode when a nested value fails to serialize (rare, e.g. non-string map keys).
Common situations: Hand-editing a record and adding an extra field or misspelling a key; tooling that rewrites meta-bucket objects with pretty-printed or restructured JSON; corruption that breaks JSON syntax mid-file; writing records with a different serde layout than the reader expects.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- invalid Effect '{0}'
- Serialization error: {0}
- Connect heartbeat state at {path} is invalid: {source}
- Connect registration token configuration is invalid
- tier probe intent is corrupt: {0}
AI-assisted analysis of rustfs/rustfs@5dca076efe (2026-09-06).
Data as JSON: /api/errors/7b23bb37c0131aab.
Report an issue: GitHub.