apache/hadoop · error · FileNotFoundException
Item not found: %s
Error message
Item not found: %s
What it means
GoogleCloudStorageFileSystem.delete throws FileNotFoundException("Item not found: <path>") when getFileInfo(path).exists() is false — deleting something that is not there. Deleting the gs:// root is rejected earlier by checkArgument. The exists-check and the actual delete are separate calls, so a path can also vanish between stat and delete.
Source
Thrown at hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorageFileSystem.java:242
}
// Create only a leaf directory because subdirectories will be inferred
// if leaf directory exists
try {
gcs.createEmptyObject(resourceId);
} catch (FileAlreadyExistsException e) {
// This means that directory object already exist, and we do not need to do anything.
LOG.trace("mkdirs: {} already exists, ignoring creation failure", resourceId, e);
}
}
void delete(URI path, boolean recursive) throws IOException {
checkNotNull(path, "path should not be null");
checkArgument(!path.equals(GCSROOT), "Cannot delete root path (%s)", path);
FileInfo fileInfo = getFileInfo(path);
if (!fileInfo.exists()) {
throw new FileNotFoundException("Item not found: " + path);
}
List<FileInfo> itemsToDelete;
// Delete sub-items if it is a directory.
if (fileInfo.isDirectory()) {
itemsToDelete =
recursive
? listRecursive(fileInfo.getPath()) // TODO: Get only one result
: listDirectory(fileInfo.getPath());
if (!itemsToDelete.isEmpty() && !recursive) {
throw new DirectoryNotEmptyException("Cannot delete a non-empty directory. : " + path);
}
} else {
itemsToDelete = new ArrayList<>();
}
List<FileInfo> bucketsToDelete = new ArrayList<>();View on GitHub (pinned to 2add963021)
Solutions
- Treat FileNotFoundException from delete as success where delete-idempotency is the goal.
- Pre-check with getFileInfo(path).exists() for clearer control flow (still combine with catching, due to the race window).
- Fix ordering/ownership in cleanup logic so only one writer deletes a given path.
Example fix
// before
fs.delete(path, true); // throws if already gone
// after
try {
fs.delete(path, true);
} catch (FileNotFoundException e) {
// already deleted by someone else: idempotent success
} Defensive patterns
Strategy: validation
Validate before calling
if (gcsFs.getFileInfo(path).exists()) {
gcsFs.delete(path, recursive);
} else {
LOG.debug("delete skipped, already gone: {}", path);
} Try / catch
catch (FileNotFoundException e) {
// someone else removed it first: treat as success for idempotent cleanup
} Prevention
- Design cleanup as idempotent: missing path == success.
- Ensure a single owner deletes each path; serialize competing cleanup jobs.
- Log deleted paths to make retried-delete races diagnosable.
When it happens
Trigger: delete(path, recursive) for a nonexistent object, bucket, or directory; concurrent deletion by another client between your listing and your delete; retrying a job whose earlier attempt already deleted the path.
Common situations: Concurrent cleanup jobs racing each other; committer cleanup removing temp files a retried task also tries to delete; typo'd paths; idempotent job retries.
Related errors
- Item not found: %s
- Deleting resource %s failed.
- Cannot delete a non-empty directory. : %s
- {}
- Multipart upload incomplete: expected {} parts but got {}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/81c45234c04c7b3f.
Report an issue: GitHub.