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

  1. Verify the exact location exists: `aws s3 ls s3://<bucket>/<prefix>/` using the same credentials Presto uses.
  2. Fix the table LOCATION / partition LOCATION in the Hive metastore (MSCK REPAIR TABLE for partitions).
  3. Check IAM policy grants s3:ListBucket and s3:GetObject on the bucket/prefix for the Presto role.
  4. Confirm the URI scheme and path spelling (s3://, s3a://, s3n://) match what the connector expects.
  5. 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

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


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/97088bd41fcd60b5. Report an issue: GitHub.