prestodb/presto · error · FileNotFoundException
File does not exist:
Error message
File does not exist:
What it means
PrestoS3FileSystem.getFileStatus throws java.io.FileNotFoundException 'File does not exist: <path>' when the path names the bucket root but getS3ObjectMetadata returns no object metadata (the bucket itself is absent/unnaccessible). Since PrestoS3FileSystem is a Hadoop FileSystem over S3, a missing key/bucket surfaces as the Hadoop-standard FileNotFoundException so callers like listStatus/directory handling can treat it uniformly.
Source
Thrown at presto-hive/src/main/java/com/facebook/presto/hive/s3/PrestoS3FileSystem.java:366
try {
return iterator.next();
}
catch (AmazonClientException e) {
throw new IOException(e);
}
}
}
@Override
public FileStatus getFileStatus(Path path)
throws IOException
{
if (path.getName().isEmpty()) {
// the bucket root requires special handling
if (getS3ObjectMetadata(path).getObjectMetadata() != null) {
return new FileStatus(0, true, 1, 0, 0, qualifiedPath(path));
}
throw new FileNotFoundException("File does not exist: " + path);
}
PrestoS3ObjectMetadata metadata = getS3ObjectMetadata(path);
if (metadata.getObjectMetadata() == null) {
// check if this path is a directory
Iterator<LocatedFileStatus> iterator = listPrefix(path, OptionalInt.of(1), ListingMode.SHALLOW_ALL);
if (iterator.hasNext()) {
return new FileStatus(0, true, 1, 0, 0, qualifiedPath(path));
}
throw new FileNotFoundException("File does not exist: " + path);
}
return new FileStatus(
getObjectSize(path, metadata.getObjectMetadata()),
// Some directories (e.g. uploaded through S3 GUI) return a charset in the Content-Type header
isDirectory(metadata),
1,View on GitHub (pinned to 55bb57d202)
Solutions
- Verify the exact location exists: `aws s3 ls s3://<bucket>/<prefix>/` using the same credentials Presto uses.
- Fix the table LOCATION / partition LOCATION in the Hive metastore (MSCK REPAIR TABLE for partitions).
- Check IAM policy grants s3:ListBucket and s3:GetObject on the bucket/prefix for the Presto role.
- Confirm the URI scheme and path spelling (s3://, s3a://, s3n://) match what the connector expects.
- Check for lifecycle/expiration rules that deleted the objects and restore them.
Example fix
// before: partition location points to deleted prefix ALTER TABLE t ADD PARTITION (ds='2026-01-01') LOCATION 's3://my-bucket/data/ds=2026-01-01/'; -- File does not exist // after: verify and correct the location aws s3 ls s3://my-bucket/data/ # find actual prefix ALTER TABLE t ADD PARTITION (ds='2026-01-01') LOCATION 's3://my-bucket/data-v2/ds=2026-01-01/';
Defensive patterns
Strategy: try-catch
Validate before calling
// verify the S3 location with the same credentials before querying
HeadBucketResponse r = s3.headBucket(b -> b.bucket(bucket)); // throws NoSuchBucketException if absent
boolean keyExists = s3.listObjectsV2(b -> b.bucket(bucket).prefix(prefix).maxKeys(1)).contents().size() > 0;
if (!keyExists) throw new IllegalStateException("S3 prefix has no objects: " + bucket + "/" + prefix); Type guard
boolean isS3FileNotFound(Throwable t) {
return t instanceof FileNotFoundException ||
(t instanceof PrestoException && t.getMessage() != null && t.getMessage().startsWith("File does not exist:"));
} Try / catch
try {
return query(sql);
} catch (Exception e) {
if (isS3FileNotFound(e)) {
// run MSCK REPAIR / fix partition locations, then retry
runSql("MSCK REPAIR TABLE " + table);
return query(sql);
}
throw e;
} Prevention
- Verify bucket/prefix spellings and scheme (s3:// vs s3a://) in table and partition locations.
- Audit S3 lifecycle/expiration policies against table retention expectations.
- Grant the Presto IAM role s3:ListBucket and s3:GetObject on all table prefixes.
- Run MSCK REPAIR TABLE after adding/removing S3 partitions.
When it happens
Trigger: getFileStatus is called (e.g., by directory() during split planning or listStatus) for a path whose S3 HEAD request returns 404: the bucket doesn't exist, the key was deleted, or credentials/IAM policy deny s3:GetObject so S3 answers 403/404.
Common situations: Typo in the S3 bucket or path in the table location (s3n/s3a vs s3 scheme mixups); querying a table whose data was deleted by an S3 lifecycle rule; wrong access keys / missing IAM permission causing metadata lookup failure; querying bucket root of a nonexistent bucket.
Related errors
- HIVE_FILE_NOT_FOUND
- HIVE_FILE_NOT_FOUND
- HIVE_FILESYSTEM_ERROR
- Error reading from file %s: %s
- GENERIC_INTERNAL_ERROR
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/97088bd41fcd60b5.
Report an issue: GitHub.