rustfs/rustfs · error · Error
NoSuchKey
NoSuchKey
Error message
File not found
What it means
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.
Source
Thrown at crates/filemeta/src/error.rs:23
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// FileMeta error type and Result alias.
/// This module defines a custom error type `Error` for handling various
/// error scenarios related to file metadata operations. It also provides
/// a `Result` type alias for convenience.
pub type Result<T> = core::result::Result<T, Error>;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("File not found")]
FileNotFound,
#[error("File version not found")]
FileVersionNotFound,
#[error("Volume not found")]
VolumeNotFound,
#[error("File corrupt")]
FileCorrupt,
#[error("Done for now")]
DoneForNow,
#[error("Method not allowed")]
MethodNotAllowed,
#[error("Unexpected error")]
Unexpected,View on GitHub (pinned to 35af688cd9)
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
Example fix
// before
let fi = meta.to_file_info(bucket, key, &opts)?; // Err(FileNotFound) propagates as a hard failure
// after
let fi = match meta.to_file_info(bucket, key, &opts) {
Ok(fi) => fi,
Err(rustfs_filemeta::Error::FileNotFound) => return Ok(None), // map to 404 NoSuchKey
Err(e) => return Err(e),
}; Defensive patterns
Strategy: try-catch
Validate before calling
// Cheap pre-check on an already-loaded FileMeta before decoding
if meta.versions.is_empty() {
return Ok(None); // nothing stored at this path — avoid the error entirely
}
let fi = meta.to_file_info(volume, path, &opts)?; Type guard
pub fn is_no_such_key(err: &rustfs_filemeta::Error) -> bool {
matches!(err, rustfs_filemeta::Error::FileNotFound)
} Try / catch
match meta.to_file_info(volume, path, &opts) {
Ok(fi) => Ok(Some(fi)),
Err(rustfs_filemeta::Error::FileNotFound) => Ok(None), // 404 NoSuchKey
Err(e) => Err(e),
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of rustfs/rustfs@35af688cd9 (2026-08-20).
Data as JSON: /api/errors/50f57189ba211ed1.
Report an issue: GitHub.