prestodb/presto · error · PrestoException
HIVE_BAD_DATA
HIVE_BAD_DATA
Error message
Error parsing symlinks
What it means
QuickStatsProvider.buildQuickStats reads symlink text files to enumerate a partition's data files; when the underlying FileSystem/LocalFileSystem throws IOException while parsing those symlink targets, the provider wraps it in a PrestoException with error code HIVE_BAD_DATA. It signals the partition's symlink data is malformed or unreadable, not a transient failure.
Source
Thrown at presto-hive/src/main/java/com/facebook/presto/hive/statistics/QuickStatsProvider.java:389
for (Map.Entry<Path, List<Path>> entry : parentToTargets.entrySet()) {
targetFileInfoList.addAll(getTargetPathsHiveFileInfos(
path,
partition,
entry.getKey(),
entry.getValue(),
hiveDirectoryContext,
fs,
directoryLister,
resolvedTable,
nameNodeStats,
session));
}
fileList = targetFileInfoList.build().iterator();
}
catch (IOException e) {
throw new PrestoException(HIVE_BAD_DATA, "Error parsing symlinks", e);
}
}
PartitionQuickStats partitionQuickStats = PartitionQuickStats.EMPTY;
Stopwatch buildStopwatch = Stopwatch.createStarted();
// Build quick stats one by one from statsBuilderStrategies. Do this until we get a non-empty PartitionQuickStats
for (QuickStatsBuilder strategy : statsBuilderStrategies) {
partitionQuickStats = strategy.buildQuickStats(session, metastore, table, metastoreContext, partitionId, fileList);
if (partitionQuickStats != PartitionQuickStats.EMPTY) {
// Strategy successfully resolved stats, don't explore other strategies
// TODO : We can order the strategies based on table metadata, e.g Iceberg tables could use the IcebergQuickStatsBuilder first
break;
}
}
long buildMillis = buildStopwatch.elapsed(MILLISECONDS);
session.getRuntimeStats().addMetricValue("QuickStatsProvider/BuildTimeMS/" + partitionKey, RuntimeUnit.NONE, buildMillis);View on GitHub (pinned to 55bb57d202)
Solutions
- Inspect and fix the symlink text file for the partition (remove/repair dangling or malformed entries)
- Verify all symlink target paths exist and are readable by the Presto user
- Check the underlying filesystem health/permissions (HDFS NameNode logs, hdfs fsck)
- Recreate the partition with a correct LOCATION/symlink metadata, e.g. via MSCK or ALTER TABLE ... ADD PARTITION
- Look at the wrapped IOException (cause) for the precise filesystem error
Example fix
// before (bad symlink file entry) hdfs://namenode/missing/path/file.orc // after (fixed symlink entry) hdfs://namenode/data/table/part=2026-01-01/file.orc
Defensive patterns
Strategy: try-catch
Validate before calling
// before buildQuickStats: validate the symlink file
for (String line : symlinkFileLines) {
Path target = new Path(line.trim());
if (!fileSystem.exists(target)) {
throw new PrestoException(HIVE_BAD_DATA, "Symlink target missing: " + target);
}
} Try / catch
try {
stats = quickStatsProvider.buildQuickStats(...);
} catch (PrestoException e) {
if (HIVE_BAD_DATA.toErrorCode().equals(e.getErrorCode())) {
LOG.error("Symlink partition data invalid: " + e.getMessage(), e);
// surface to user / fail query with a clear message
}
throw e;
} Prevention
- Never hand-edit symlink text files; regenerate them from a job
- Validate all symlink targets exist before swapping partition metadata
- Monitor for IOException causes in Hive logs around symlink partitions
- Use standard (non-symlink) partition layouts unless symlink support is required
When it happens
Trigger: A Hive partition defined with symlink-style location whose symlink file contains bad paths, unreadable targets, or the underlying filesystem raises IOException during targetFileInfo resolution.
Common situations: Manually edited symlink text files with dangling or malformed targets; permissions/missing files referenced by symlinks; partitions moved or renamed without updating symlink files; HDFS outages during listing.
Related errors
- HIVE_FILESYSTEM_ERROR
- HIVE_FILESYSTEM_ERROR
- HIVE_FILESYSTEM_ERROR
- HIVE_WRITER_CLOSE_ERROR
- HIVE_WRITER_OPEN_ERROR
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/7224f42a6b063b02.
Report an issue: GitHub.