hyperledger/fabric · error
refusing to copy absolute symlink %s -> %s
Error message
refusing to copy absolute symlink %s -> %s
What it means
copySymlink (used by CopyDir when walking external builder package contents) reads the symlink target with os.Readlink and rejects symlinks whose target is an absolute path. Absolute symlinks are considered unsafe to reproduce in the destination because they can point anywhere on the host filesystem. The copy is aborted and the destination is cleaned up.
Source
Thrown at core/container/externalbuilder/copy.go:66
})
// If an error occurred, clean up any created files.
if err != nil {
if err := os.RemoveAll(destroot); err != nil {
logger.Errorf("failed to remove destination directory %s after copy error: %s", destroot, err)
}
return errors.WithMessagef(err, "failed to copy %s to %s", srcroot, destroot)
}
return nil
}
func copySymlink(srcroot, srcpath, destpath string) error {
// If the symlink is absolute, then we do not want to copy it.
symlinkDest, err := os.Readlink(srcpath)
if err != nil {
return err
}
if filepath.IsAbs(symlinkDest) {
return errors.Errorf("refusing to copy absolute symlink %s -> %s", srcpath, symlinkDest)
}
// Determine where the symlink points to. If it points outside
// of the source root, then we do not want to copy it.
symlinkDir := filepath.Dir(srcpath)
symlinkTarget := filepath.Clean(filepath.Join(symlinkDir, symlinkDest))
relativeTarget, err := filepath.Rel(srcroot, symlinkTarget)
if err != nil {
return err
}
if relativeTargetElements := strings.Split(relativeTarget, string(os.PathSeparator)); len(relativeTargetElements) >= 1 && relativeTargetElements[0] == ".." {
return errors.Errorf("refusing to copy symlink %s -> %s pointing outside of source root", srcpath, symlinkDest)
}
return os.Symlink(symlinkDest, destpath)
}
func copyFile(srcpath, destpath string) error {View on GitHub (pinned to 2736b63f8f)
Solutions
- Find and fix the offending link: 'find <srcroot> -type l -exec ls -l {} +' and rewrite it to a relative target (e.g. ln -sfn ../lib/foo foo).
- Remove unnecessary absolute symlinks from the chaincode package before install.
- Recreate the symlink at deploy/runtime (e.g. in the builder's build or release script) rather than shipping it in the source tree.
- If the symlink must remain, restructure directories so a relative path can express the target inside the source root.
Example fix
// before ln -s /opt/tools/bin/cli ./bin/cli // absolute, refused // after cd bin && ln -sfn ../../opt/tools/bin/cli cli // relative target inside tree (if valid) // or remove the symlink entirely
Defensive patterns
Strategy: validation
Validate before calling
// shell: detect absolute symlinks in a package before install
// find <pkgdir> -type l -exec readlink {} \; | grep -E '^/' && echo "absolute symlinks present" && exit 1 Try / catch
// Go caller of CopyDir
if err := CopyDir(logger, src, dst); err != nil {
if strings.Contains(err.Error(), "refusing to copy absolute symlink") {
// rewrite the reported link to a relative target and retry
}
} Prevention
- Always create symlinks with relative targets inside the package tree.
- Scan packages for absolute symlinks in CI before install/approve.
- Re-vendor dependencies that contain machine-specific absolute symlinks.
- Recreate symlinks in the builder's build/release phase instead of shipping them.
When it happens
Trigger: copySymlink is invoked from the CopyDir filepath.Walk callback (anonymous walk function) on any symlink entry whose os.Readlink target begins with '/' (filepath.IsAbs true).
Common situations: Source trees checked out or built on another machine containing absolute symlinks (e.g. -> /usr/lib/somelib); symlinks created by absolute-path installs; Node.js packages vendored with machine-specific absolute links.
Related errors
- refusing to copy symlink %s -> %s pointing outside of source
- refusing to copy unsupported file %s with mode %o
- peer will not accept external chaincode connection %s (excep
- chaincode %s attempted to write to the namespace of LSCC
- no DockerBuilder, cannot build
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/113edb1b2afbad18.
Report an issue: GitHub.