{"record":{"id":"7b23bb37c0131aab","repo":"rustfs/rustfs","slug":"tier-probe-intent-json-error-0","errorCode":null,"errorMessage":"tier probe intent json error: {0}","messagePattern":"tier probe intent json error: (.+?)","errorType":"error_code","errorClass":"TierProbeIntentError","httpStatus":null,"severity":"error","filePath":"crates/ecstore/src/services/tier/tier_probe_intent.rs","lineNumber":49,"sourceCode":"pub(crate) const MAX_TIER_PROBE_INTENT_SIZE: usize = 64 * 1024;\nconst TIER_PROBE_OBJECT_PREFIX: &str = \"rustfs-tier-probe-\";\n\npub(crate) type Result<T> = std::result::Result<T, TierProbeIntentError>;\n\n#[derive(Debug, thiserror::Error)]\npub(crate) enum TierProbeIntentError {\n    #[error(\"tier probe intent is corrupt: {0}\")]\n    Corrupt(&'static str),\n    #[error(\"tier probe intent schema is unsupported: {0}\")]\n    UnsupportedSchema(String),\n    #[error(\"tier probe intent checksum mismatch\")]\n    ChecksumMismatch,\n    #[error(\"invalid tier probe intent state change from {from:?} to {to:?}\")]\n    InvalidStateChange {\n        from: TierProbeIntentState,\n        to: TierProbeIntentState,\n    },\n    #[error(\"tier probe intent json error: {0}\")]\n    Json(#[from] serde_json::Error),\n}\n\n#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"snake_case\")]\npub(crate) enum TierProbeIntentState {\n    UploadOutcomeUnknown,\n    Uploaded,\n    CleanupPending,\n    AbortedNoRemote,\n    Completed,\n}\n\n#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]\n#[serde(rename_all = \"snake_case\")]\npub(crate) enum TierProbeRemoteVersionKind {\n    #[default]\n    Unknown,","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/rustfs/rustfs/blob/5dca076efed96e7b842de07c4c2111035ae7c7a2/crates/ecstore/src/services/tier/tier_probe_intent.rs#L31-L67","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before: extra/misspelled fields rejected by deny_unknown_fields\n{\"schema\":\"rustfs-tier-probe-intent-v1\",\"content_sha256\":\"...\",\"intent\":{...,\"tier_namee\":\"COLD-A\"}}\n// after: strict, canonical envelope with only known fields\n{\"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 */}}","handlingStrategy":"try-catch","validationCode":"fn is_strict_envelope(data: &[u8]) -> bool {\n    serde_json::from_slice::<PersistedTierProbeIntent>(data).is_ok()\n}","typeGuard":null,"tryCatchPattern":"match TierProbeIntent::decode(probe_id, &data) {\n    Ok(intent) => use_intent(intent),\n    Err(TierProbeIntentError::Json(e)) => {\n        tracing::warn!(error = %e, \"tier probe intent envelope failed strict JSON parse\");\n        delete_corrupt_record_and_reprobe(probe_id).await?;\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["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."],"tags":["rust","serde","json","storage","ilm-tiering"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"5dca076efed96e7b842de07c4c2111035ae7c7a2","analyzedAt":"2026-09-06T05:54:05.891Z","contentChangedAt":"2026-09-06T05:54:05.891Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}