1. Overview
In this article, we’ll have a look at how to solve the “Too many levels of symbolic links” error when we want to use a symlink.
2. Using the ln Command To Create Symbolic Links
To create a symlink using the ln command, we need to pass the –s or –symbolic option:
$ ln -s A B
The GNU manual for ln shows the source as TARGET and the destination as LINK_NAME:
ln [OPTION]... [-T] TARGET LINK_NAME
This naming convention might be confusing for some people, so it’s probably helpful to remind ourselves that ln is like cp and mv: the source (A) needs to come first, followed by the destination (B).
Or we can just say it naturally: We are creating a symbolic link to A, and we want to call it B.
3. The Problem: “Too many levels of symbolic links” Error
Let’s say we have the following directory structure:
$ tree --noreport -fp
.
└── [drwxr-xr-x] ./topdir
├── [drwxr-xr-x] ./topdir/source
└── [drwxr-xr-x] ./topdir/outputdir
We then create a symlink and expect that the created outputdir/source symlink will point to the source directory:
$ cd /topdir
$ ln -s source outputdir
$ tree --noreport -fp
.
├── [drwxr-xr-x] ./source
└── [drwxr-xr-x] ./outputdir
└── [lrwxrwxrwx] ./outputdir/source -> source
The symlink was created, but it is actually broken.
We can find all broken symlinks with the find command:
$ find -L -xtype l
find: ‘./test/outputdir/source’: Too many levels of symbolic links
The reason for this error is that symbolic links with relative sources are always relative to the symlink directory, not the directory from where we created the link.
So, the symlink /topdir/outputdir/source that we just created points to /topdir/outputdir/source instead of /topdir/source.
Let’s take a look at another example.
Let’s say we have this directory structure. Then, after we create the symlink, we can check if the symlink is good:
$ cd /topdir
$ tree --noreport -fp
.
└── [drwxr-xr-x] ./test
├── [drwxr-xr-x] ./test/source
└── [drwxr-xr-x] ./test/outputdir
$ ln -s test/source test/outputdir
$ tree --noreport -fp
.
└── [drwxr-xr-x] ./test
├── [drwxr-xr-x] ./test/source
└── [drwxr-xr-x] ./test/outputdir
└── [lrwxrwxrwx] ./test/outputdir/source -> test/source
$ find -L -xtype l
./test/outputdir/source
The symlink that we just created – /topdir/test/outputdir/source – is also broken because it’s pointing to a non-existent directory.
Instead of pointing to /topdir/test/source, it is pointing to /topdir/test/outputdir/test/source.
There are two ways to fix this. Let’s have a look in the next sections.
4. Use an Absolute Path
We can use an absolute path for the source parameter:
$ cd /topdir
$ ln -s "$(pwd)/source" outputdir
$ tree --noreport -fp
.
├── [drwxr-xr-x] ./source
└── [drwxr-xr-x] ./outputdir
└── [lrwxrwxrwx] ./outputdir/source -> /topdir/source
Let’s verify that the link is working:
$ cd /topdir
$ touch /topdir/source/sample.txt
$ tree --noreport -fp
.
├── [drwxr-xr-x] ./source
│ └── [-rw-r--r--] ./source/sample.txt
└── [drwxr-xr-x] ./outputdir
└── [lrwxrwxrwx] ./outputdir/source -> /topdir/source
$ cd outputdir/source
$ ls -l
total 0
-rw-r--r-- 1 baeldung baeldung 0 Aug 3 20:51 sample.txt
As we can see above, we’ve successfully used the symlink to access the source directory and list all the files.
The downside of making symlinks to absolute paths is that they are easily broken when the directory names change.
5. Use a Relative Path
Another way to solve the error is to use a relative path for the source parameter:
$ cd /topdir
$ ln -s ../source outputdir
$ tree --noreport -fp
.
├── [drwxr-xr-x] ./source
│ └── [-rw-r--r--] ./source/sample.txt
└── [drwxr-xr-x] ./outputdir
└── [lrwxrwxrwx] ./outputdir/source -> ../source
$ ls outputdir/source -l
lrwxrwxrwx 1 baeldung baeldung 9 Aug 3 21:11 outputdir/source -> ../source
We can use the -r or –relative option for the ln command to generate the source path automatically:
$ cd /topdir
$ ln -sr source outputdir
$ tree --noreport -fp
.
├── [drwxr-xr-x] ./source
│ └── [-rw-r--r--] ./source/sample.txt
└── [drwxr-xr-x] ./outputdir
└── [lrwxrwxrwx] ./outputdir/source -> ../source
$ ls outputdir/source -l
lrwxrwxrwx 1 baeldung baeldung 9 Aug 3 21:11 outputdir/source -> ../source
We have successfully used the symlink to access the source directory and list all the files.
6. Conclusion
In this article, we’ve seen that symbolic links with relative sources are always relative to the symlink directory, not the directory from where we created the link. There are two ways to solve the “Too many levels of symbolic links” error. We can pass the source parameter as either an absolute or relative path.