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.

Authors Bottom

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

Comments are closed on this article!