{"record":{"id":"50f57189ba211ed1","repo":"rustfs/rustfs","slug":"nosuchkey-50f571","errorCode":"NoSuchKey","errorMessage":"File not found","messagePattern":"File not found","errorType":"exception","errorClass":"Error","httpStatus":404,"severity":"error","filePath":"crates/filemeta/src/error.rs","lineNumber":23,"sourceCode":"// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n/// FileMeta error type and Result alias.\n/// This module defines a custom error type `Error` for handling various\n/// error scenarios related to file metadata operations. It also provides\n/// a `Result` type alias for convenience.\npub type Result<T> = core::result::Result<T, Error>;\n\n#[derive(thiserror::Error, Debug)]\npub enum Error {\n    #[error(\"File not found\")]\n    FileNotFound,\n    #[error(\"File version not found\")]\n    FileVersionNotFound,\n\n    #[error(\"Volume not found\")]\n    VolumeNotFound,\n\n    #[error(\"File corrupt\")]\n    FileCorrupt,\n\n    #[error(\"Done for now\")]\n    DoneForNow,\n\n    #[error(\"Method not allowed\")]\n    MethodNotAllowed,\n\n    #[error(\"Unexpected error\")]\n    Unexpected,","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/rustfs/rustfs/blob/35af688cd9d41b4346fbe27dcf7250ba72046c1f/crates/filemeta/src/error.rs#L5-L41","documentation":"The core object-absence error of rustfs-filemeta. It is returned when an xl.meta lookup finds no usable version for the requested path: get_idx with an index at or past versions.len() (crates/filemeta/src/filemeta.rs:268-274), to_file_info when no version matches and no versionId was supplied (filemeta.rs:848-872), and metacache bucket lookups (metacache.rs:313,320). The disk layer converts it to DiskError::FileNotFound (crates/ecstore/src/disk/error.rs:296) and the S3 API surfaces it as 404 NoSuchKey.","triggerScenarios":"FileMeta find/to_file_info on a key that was never written; stat after the object was deleted; reading an object whose only versions are free (tier-free) versions while include_free_versions is false; calling get_idx with a stale index after version compaction.","commonSituations":"GET/HEAD/DELETE on a misspelled key; racing a concurrent delete between ListObjects and GetObject; wrong bucket/prefix in the request path; test fixtures that never wrote data; S3 clients observing NoSuchKey after another client removed the object.","solutions":["Verify the exact key and bucket with a stat or listing call","Treat the error as a normal 404 in the caller (return, skip, or report) instead of retrying blindly","If tiering is in play, request free versions or follow the transition metadata before concluding the object is gone","For concurrent-delete races, re-list once before giving up"],"exampleFix":"// before\nlet fi = meta.to_file_info(bucket, key, &opts)?; // Err(FileNotFound) propagates as a hard failure\n\n// after\nlet fi = match meta.to_file_info(bucket, key, &opts) {\n    Ok(fi) => fi,\n    Err(rustfs_filemeta::Error::FileNotFound) => return Ok(None), // map to 404 NoSuchKey\n    Err(e) => return Err(e),\n};","handlingStrategy":"try-catch","validationCode":"// Cheap pre-check on an already-loaded FileMeta before decoding\nif meta.versions.is_empty() {\n    return Ok(None); // nothing stored at this path — avoid the error entirely\n}\nlet fi = meta.to_file_info(volume, path, &opts)?;","typeGuard":"pub fn is_no_such_key(err: &rustfs_filemeta::Error) -> bool {\n    matches!(err, rustfs_filemeta::Error::FileNotFound)\n}","tryCatchPattern":"match meta.to_file_info(volume, path, &opts) {\n    Ok(fi) => Ok(Some(fi)),\n    Err(rustfs_filemeta::Error::FileNotFound) => Ok(None), // 404 NoSuchKey\n    Err(e) => Err(e),\n}","preventionTips":["Stat or list before acting on user-supplied keys","Map FileNotFound to a typed Option at the storage boundary instead of propagating it inward","In quorum reads, treat FileNotFound as one disk's vote, not an immediate failure","Re-list once after a suspected concurrent delete instead of retrying blindly"],"tags":["rust","rustfs","filemeta","object-storage","not-found"],"backgroundTag":"s3-no-such-key","analyzedSha":"35af688cd9d41b4346fbe27dcf7250ba72046c1f","analyzedAt":"2026-08-20T21:57:04.799Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}