{"record":{"id":"bf9bc9d6d4500da2","repo":"rustfs/rustfs","slug":"failed-to-build-uri-from-parts-reason","errorCode":null,"errorMessage":"failed to build uri from parts: {reason}","messagePattern":"failed to build uri from parts: (.+?)","errorType":"exception","errorClass":"SignV2Error","httpStatus":null,"severity":"warning","filePath":"crates/signer/src/request_signature_v2.rs","lineNumber":52,"sourceCode":"// Phase 3: Default to SHA-256, SHA-1 becomes optional\n// See https://github.com/rustfs/backlog/issues/747 for discussion.\n\nconst _SIGN_V4_ALGORITHM: &str = \"AWS4-HMAC-SHA256\";\nconst SIGN_V2_ALGORITHM: &str = \"AWS\";\n\n#[derive(Debug, thiserror::Error)]\npub enum SignV2Error {\n    #[error(\"invalid UTF-8 header value for `{name}`\")]\n    InvalidHeaderValue { name: String },\n    #[error(\"failed to format signing timestamp: {reason}\")]\n    TimeFormat { reason: String },\n    #[error(\"failed to build signing timestamp: {reason}\")]\n    TimeComponent { reason: String },\n    #[error(\"failed to encode query parameters: {reason}\")]\n    QueryEncode { reason: String },\n    #[error(\"failed to parse uri: {reason}\")]\n    InvalidUri { reason: String },\n    #[error(\"failed to build uri from parts: {reason}\")]\n    InvalidUriParts { reason: String },\n    #[error(\"failed to convert canonical headers to UTF-8: {reason}\")]\n    CanonicalUtf8 { reason: String },\n    #[error(\"failed to parse header value for `{name}`: {reason}\")]\n    HeaderValueParse { name: String, reason: String },\n    #[error(\"failed to resolve host address: {0}\")]\n    HostAddr(#[from] HostAddrError),\n}\n\n#[derive(Debug)]\nstruct SignV2Failure {\n    request: request::Request<Body>,\n    error: SignV2Error,\n}\n\ntype SignV2Outcome = std::result::Result<request::Request<Body>, Box<SignV2Failure>>;\n\nfn sign_v2_fail(request: request::Request<Body>, error: SignV2Error) -> SignV2Outcome {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/rustfs/rustfs/blob/35af688cd9d41b4346fbe27dcf7250ba72046c1f/crates/signer/src/request_signature_v2.rs#L34-L70","documentation":"SignV2Error::InvalidUriParts is returned by pre_sign_v2_inner at request_signature_v2.rs:142-145 when http::Uri::from_parts rejects the reassembled URI. The parts are cloned from a URI that already parsed successfully (lines 131-132), so scheme and authority are known-valid, and the new PathAndQuery was validated on the immediately preceding line. The variant is therefore defensive and effectively unreachable in this revision.","triggerScenarios":"No input reaches it in a consistent build: every component handed to Uri::from_parts was already validated. Only memory corruption of the parts struct or a locally modified signer could trigger it.","commonSituations":"Encountered almost exclusively as an exhaustiveness-match arm, or after someone hand-builds URIs via into_parts/from_parts elsewhere and attributes the failure here. If genuinely observed, capture the original URI and report upstream.","solutions":["Treat as an invariant violation: log the request URI and file an upstream issue rather than changing inputs.","Use try_pre_sign_v2 so any occurrence surfaces with the reason string from Uri::from_parts instead of being swallowed.","Verify the crate version actually built matches this source."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn is_invalid_uri_parts(e: &SignV2Error) -> bool {\n    matches!(e, SignV2Error::InvalidUriParts { .. })\n}","tryCatchPattern":"Err(e @ SignV2Error::InvalidUriParts { .. }) => {\n    // defensive variant: from_parts on already-validated parts; report upstream\n    tracing::error!(error = %e, \"signer invariant violated\");\n    return Err(anyhow!(\"signer invariant violated\"));\n}","preventionTips":["Do not hand-assemble URIs via into_parts/from_parts before presigning; use absolute-form URIs.","Keep the try_ API in calling code so defensive variants are observable."],"tags":["rust","rustfs","s3","signing","sigv2","presign","uri","dead-variant"],"backgroundTag":"invalid-uri-parts","analyzedSha":"35af688cd9d41b4346fbe27dcf7250ba72046c1f","analyzedAt":"2026-08-20T21:57:04.799Z","contentChangedAt":"2026-08-20T21:57:04.799Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}