From 8cc62630fb44e742703dcf7cd66168b7f749ad89 Mon Sep 17 00:00:00 2001 From: Dave Bunten Date: Sun, 23 Aug 2026 17:02:50 -0600 Subject: [PATCH] GH-24093: [C++] Fix GetFileInfo for zero-byte S3 directory markers S3 keys form a flat list. A key can look like a folder path, but S3 does not enforce real folders. Some tools create a zero-byte object to mark a folder. This marker can use the exact same key as a folder that also holds real files. GetFileInfo did not check for this case. It read the zero-byte marker as a file. Parquet reads then failed with the error "Invalid Parquet file size is 0 bytes". GetFileInfo now checks zero-byte objects for files nested under them. If nested files exist, it reports the path as a directory, not a file. The recursive directory listing already handled this for markers with a trailing slash; this fix covers the direct GetFileInfo lookup on a single path. --- cpp/src/arrow/filesystem/s3fs.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cpp/src/arrow/filesystem/s3fs.cc b/cpp/src/arrow/filesystem/s3fs.cc index 0c15f6f18444..0438a7bc2249 100644 --- a/cpp/src/arrow/filesystem/s3fs.cc +++ b/cpp/src/arrow/filesystem/s3fs.cc @@ -3117,6 +3117,18 @@ Result S3FileSystem::GetFileInfo(const std::string& s) { if (outcome.IsSuccess()) { // "File" object found FileObjectToInfo(path.key, outcome.GetResult(), &info); + if (info.type() == FileType::File && info.size() == 0) { + // GH-24093: some third-party tools create zero-byte "directory marker" + // objects that use neither a trailing slash nor the conventional + // "application/x-directory" content type, so IsDirectory() above + // doesn't recognize them. If other objects exist nested under this + // key, treat it as a directory rather than an (invalid) empty file. + ARROW_ASSIGN_OR_RAISE(bool is_dir, impl_->IsNonEmptyDirectory(path)); + if (is_dir) { + info.set_type(FileType::Directory); + info.set_size(kNoSize); + } + } return info; } impl_->GetOrSetBackend(outcome.GetError());