rustfs/rustfs · error · SealedCredentialError

unsupported sealed credential envelope version {0}

Error message

unsupported sealed credential envelope version {0}

What it means

SealedCredentialError::UnsupportedVersion(v) is thrown when a stored sealed-credential envelope carries a format version the reader does not know — typically an envelope written by a newer release. The library refuses to guess or parse unknown formats, so the record cannot be unsealed by this binary. It is a forward-compatibility guard against silently misreading binary data.

Source

Thrown at crates/ecstore/src/bucket/sealed_credentials.rs:148

        if self.v == SEALED_CREDENTIAL_VERSION {
            Ok(())
        } else {
            Err(SealedCredentialError::UnsupportedVersion(self.v))
        }
    }
}

/// Why a seal or unseal did not produce a usable value. Every variant is
/// terminal for the record that carried it: a caller reports the remote as
/// unusable, and never substitutes a default or empty credential.
#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
pub enum SealedCredentialError {
    /// No sealer is installed: KMS is not configured, or the process has not
    /// finished startup. Reading a sealed record is impossible here.
    #[error("no credential sealer is installed")]
    NoSealer,
    /// The stored envelope is from a newer (or otherwise unknown) format.
    #[error("unsupported sealed credential envelope version {0}")]
    UnsupportedVersion(u8),
    /// The stored bytes are not a well-formed envelope.
    #[error("malformed sealed credential: {0}")]
    Malformed(String),
    /// The sealer refused: wrong encryption context, missing key, revoked
    /// access, or a failed authentication tag.
    #[error("sealed credential could not be unsealed: {0}")]
    Kms(String),
}

/// The KMS-backed half, installed by the binary at startup.
#[async_trait]
pub trait CredentialSealer: Send + Sync + 'static {
    /// Wraps `plaintext` under the scope's encryption context.
    async fn seal(&self, plaintext: &str, scope: &SealScope) -> Result<SealedCredential, SealedCredentialError>;

    /// Unwraps a stored envelope. Must fail when the envelope was sealed
    /// under a different scope.

View on GitHub (pinned to 5dca076efe)

Solutions

  1. Upgrade the binary to a version that supports the envelope version in the message
  2. If the rollback is intentional, reseal/rewrite the credentials with the old (supported) version using a binary that can read them
  3. Keep cluster versions homogeneous or complete the rolling upgrade before reading records written by newer nodes
  4. Check release notes for sealed-credential format changes before downgrading

Example fix

// before: reading with old binary
// error: unsupported sealed credential envelope version 3
// after: upgrade first
rustfs-upgrade --to 1.x   # binary that supports envelope v3
# then restart the service and re-read the record
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

fn is_unsupported_version(e: &SealedCredentialError) -> Option<u8> {
    if let SealedCredentialError::UnsupportedVersion(v) = e { Some(*v) } else { None }
}

Try / catch

match store.load_sealed_credential(id).await {
    Err(SealedCredentialError::UnsupportedVersion(v)) => {
        // surface version for upgrade guidance; never attempt a guess-parse
        return Err(UpgradeRequired { envelope_version: v });
    }
    r => r.map_err(Into::into),
}

Prevention

When it happens

Trigger: Reading a sealed credential whose envelope header version byte exceeds the current implementation's maximum supported version; running an older binary against data produced by a newer RustFS version; mixed-version cluster where a node reads metadata written by upgraded peers.

Common situations: Rolling upgrades where an old node reads newly written records; restoring a backup from a newer version into an older deployment; downgraded binary after an upgrade.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of rustfs/rustfs@5dca076efe (2026-09-06). Data as JSON: /api/errors/307dc70cc3ee6dda. Report an issue: GitHub.