apache/hadoop · error · IOException
Possible cyclic loop while following symbolic link " + origi
Error message
Possible cyclic loop while following symbolic link " + original
What it means
Thrown in Stat.parseExecResult when stat output ends with 'Too many levels of symbolic links' (ELOOP). Stat catches this specific errno text and rethrows as IOException flagging a probable cycle, because following the symlink chain (dereference mode, stat -L) hit the kernel's symlink-depth limit.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/Stat.java:124
"stat is not supported on this platform");
}
}
@Override
protected void parseExecResult(BufferedReader lines) throws IOException {
// Reset stat
stat = null;
String line = lines.readLine();
if (line == null) {
throw new IOException("Unable to stat path: " + original);
}
if (line.endsWith("No such file or directory") ||
line.endsWith("Not a directory")) {
throw new FileNotFoundException("File " + original + " does not exist");
}
if (line.endsWith("Too many levels of symbolic links")) {
throw new IOException("Possible cyclic loop while following symbolic" +
" link " + original);
}
// 6,symbolic link,6,1373584236,1373584236,lrwxrwxrwx,andrew,andrew,`link' -> `target'
// OR
// 6,symbolic link,6,1373584236,1373584236,lrwxrwxrwx,andrew,andrew,'link' -> 'target'
StringTokenizer tokens = new StringTokenizer(line, ",");
try {
long length = Long.parseLong(tokens.nextToken());
boolean isDir = tokens.nextToken().equalsIgnoreCase("directory") ? true
: false;
// Convert from seconds to milliseconds
long modTime = Long.parseLong(tokens.nextToken())*1000;
long accessTime = Long.parseLong(tokens.nextToken())*1000;
String octalPerms = tokens.nextToken();
// FreeBSD has extra digits beyond 4, truncate them
if (octalPerms.length() > 4) {
int len = octalPerms.length();
octalPerms = octalPerms.substring(len-4, len);View on GitHub (pinned to 2add963021)
Solutions
- Lstat the link instead: construct Stat with dereference=false, or use fs.getFileLinkStatus(p) which does not follow links
- Find and break the cycle: walk getFileLinkStatus until revisiting a target, then delete or repoint one link
- Guard tree walks against revisiting already-seen symlink targets
Example fix
// before FileStatus st = new Stat(path, true, shell).getFileStatus(); // follows links, ELOOP // after FileStatus st = new Stat(path, false, shell).getFileStatus(); // lstat semantics
Defensive patterns
Strategy: validation
Validate before calling
// do not follow links when a cycle is possible boolean dereference = false; FileStatus st = new Stat(path, dereference, shell).getFileStatus(); // or link-only status: fs.getFileLinkStatus(p)
Try / catch
try {
st = new Stat(path, true, shell).getFileStatus();
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("cyclic")) {
// ELOOP detected: switch to lstat and break the loop
st = new Stat(path, false, shell).getFileStatus();
} else {
throw e;
}
} Prevention
- Default to dereference=false unless you must resolve the final target
- Track visited symlink targets in tree walks and stop when a target repeats
When it happens
Trigger: new Stat(path, true, shell) (dereference=true) where path is a symlink that points back into its own chain: a -> b, b -> a, or link pointing to an ancestor directory containing itself.
Common situations: Build/cleanup scripts walking directory trees that contain self-referential links; test fixtures that create circular links deliberately; migration artifacts where a link and its target were swapped.
Related errors
- Filesystem does not support symlinks!
- Symlinks not supported
- Unable to create symlink to non-local file system: " + targe
- Error " + result + " creating symlink " + link + " to " + ta
- stat is not supported on this platform
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/d88d4f8524e147f8.
Report an issue: GitHub.