rustfs/rustfs · warning · std::io::Error
invalid X-Amz-Content-Sha256 header value: {err}
Error message
invalid X-Amz-Content-Sha256 header value: {err} What it means
Before signing a bucket-location request with SigV4, the client parses its own X-Amz-Content-Sha256 constant (the empty-body SHA-256 hex digest, or the literal UNSIGNED-PAYLOAD when secure) into a HeaderValue; this error fires if that constant is not a valid header value. In unmodified builds both constants are well-formed ASCII, so hitting this indicates corrupted constants or a modified fork of rustfs-utils/signer.
Source
Thrown at crates/ecstore/src/client/bucket_cache.rs:188
signer_type = SignatureType::SignatureAnonymous
}
if signer_type == SignatureType::SignatureAnonymous {
return Ok(req);
}
if signer_type == SignatureType::SignatureV2 {
let req = rustfs_signer::sign_v2(req, 0, &access_key_id, &secret_access_key, is_virtual_style);
return Ok(req);
}
let mut content_sha256 = EMPTY_STRING_SHA256_HASH.to_string();
if self.secure {
content_sha256 = UNSIGNED_PAYLOAD.to_string();
}
let content_sha256_value = content_sha256.parse().map_err(|err| {
std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("invalid X-Amz-Content-Sha256 header value: {err}"),
)
})?;
req.headers_mut().insert("X-Amz-Content-Sha256", content_sha256_value);
let req = rustfs_signer::try_sign_v4(req, 0, &access_key_id, &secret_access_key, &session_token, "us-east-1")
.map_err(|err| signer_error_to_io_error("failed to sign bucket location request", err))?;
Ok(req)
}
}
async fn process_bucket_location_response(
mut resp: http::Response<Incoming>,
bucket_name: &str,
tier_type: &str,
) -> Result<String, std::io::Error> {
//if resp != nil {
if resp.status() != StatusCode::OK {View on GitHub (pinned to 9e6e02ea09)
Solutions
- Treat it as a source/build integrity problem: diff your rustfs-utils and rustfs-signer crates against upstream releases.
- Restore EMPTY_STRING_SHA256_HASH to the 64-character hex of the empty input and UNSIGNED_PAYLOAD to the literal string UNSIGNED-PAYLOAD.
- If it reproduces with pristine dependencies, report it upstream with the constant values observed in your build.
Defensive patterns
Strategy: try-catch
Try / catch
match build_and_sign_location_request(...) {
Ok(req) => Ok(req),
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput => {
tracing::error!(event = "signing_constant_invalid", "X-Amz-Content-Sha256 constant is not a valid header; treat as build integrity failure");
Err(e)
}
Err(e) => Err(e),
} Prevention
- Pin rustfs-utils and rustfs-signer to released versions in Cargo.lock.
- In forks, add a unit test asserting EMPTY_STRING_SHA256_HASH parses as a HeaderValue and equals the empty-input SHA-256.
- Treat any occurrence as a compromised build until proven otherwise.
When it happens
Trigger: Executing the SigV4 bucket-location path while EMPTY_STRING_SHA256_HASH or UNSIGNED_PAYLOAD has been changed to a value containing non-ASCII or illegal bytes - i.e., a patched or corrupted dependency, not any runtime input.
Common situations: Custom forks that patched hash constants; build-environment drift producing a modified vendored rustfs-utils; essentially never observed in stock builds, which is why the error is defensive.
Related errors
- {}: invalid UTF-8 header value for `{}` [rustfs_signer_heade
- unexpected GetBucketVersioning XML namespace
- host is none
- remote object version id is not valid ASCII
- remote tier returned an empty object version id header
AI-assisted analysis of rustfs/rustfs@9e6e02ea09 (2026-08-16).
Data as JSON: /api/errors/9ceae0e0832350a1.
Report an issue: GitHub.