diff --git a/pseudo_util.c b/pseudo_util.c
index 3a06027..2b0cc04 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -729,7 +729,21 @@ pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurre
 			linkbuf[linklen] = '\0';
 			/* absolute symlink means go back to root */
 			if (*linkbuf == '/') {
+				size_t rootlen = root - newpath;
 				current = root;
+				/* If we're in a chroot (rootlen > 0) and the
+				 * symlink target starts with the chroot prefix,
+				 * strip it.  This happens when symlinkat expanded
+				 * an absolute target to include the chroot path
+				 * on disk; without stripping, we'd double-apply
+				 * the chroot prefix during resolution.
+				 */
+				if (rootlen > 0 && (size_t)linklen > rootlen &&
+				    !memcmp(linkbuf, newpath, rootlen) &&
+				    (linkbuf[rootlen] == '/' || linkbuf[rootlen] == '\0')) {
+					memmove(linkbuf, linkbuf + rootlen, linklen - rootlen + 1);
+					linklen -= rootlen;
+				}
 			} else {
 #ifdef PSEUDO_PORT_LINUX
 				if (is_proc) {
