Store Symbolic Links in JFrog Artifactory

The JFrog CLI can upload and download symbolic links (soft links) between your machine and JFrog Artifactory on Linux and macOS, storing them as metadata-backed zero-byte artifacts instead of resolving to the target file by default.

πŸ“˜

Prerequisite

A JFrog server must be configured with jf config add, and the target repository must exist before you run these commands. For more information, see Configuring the CLI.

πŸ“˜

Platform note

The --symlinks and --validate-symlinks options are supported only on Linux and macOS. These flags have no effect on Windows.

Symlinks are stored in Artifactory as zero-byte files with the following properties:

  • symlink.dest: The path on the original file system to which the symlink points.
  • symlink.destsha1: The SHA1 checksum of the contents of the file that symlink.dest points to. Used by --validate-symlinks during download to detect if the target file has been modified or replaced. This property is only populated when the symlink target is a regular file. If the target is a directory or does not exist at upload time, symlink.destsha1 will not be set.

Upload Symbolic Links

To upload a symlink as a symlink (not as the resolved file):

  1. Use jf rt upload with --symlinks=true.
πŸ“˜

Default symlink behavior

By default, --symlinks is false. When you omit this flag, the CLI uploads the file the symlink points to, not the symlink itself.

πŸ“˜

Absolute paths and directory layout

When you upload with an absolute source path, the CLI preserves the full directory structure inside the target repository path. Use --flat=true to upload only the file without the intermediate directories.

  1. Run:
jf rt upload <local-symlink-path> <repository-key>/<path>/ --symlinks=true --flat=true

Where:

  • <local-symlink-path> β€” Path to the symlink on your machine.
  • <repository-key> β€” Target JFrog Artifactory repository key.
  • <path> β€” Path inside the repository.

Example:

jf rt upload "/home/build/app/link.so" my-generic-repo/releases/ --symlinks=true --flat=true

Expected output:

{
  "status": "success",
  "totals": {
    "success": 1,
    "failure": 0
  }
}

Download Symbolic Links with Validation

To download symlinks and validate that targets match recorded checksums:

  1. Use jf rt download with --validate-symlinks=true so the CLI checks that each symlink target still exists and matches symlink.destsha1.
πŸ“˜

Validation scope

Symlink validation applies to files only, not directories.

πŸ“˜

Platform note

The --validate-symlinks option is supported only on Linux and macOS. This flag has no effect on Windows.

πŸ“˜

Download directory layout

By default, the CLI reproduces the repository sub-path structure inside the local destination directory. When you download my-repository/path/symlink into /local/path/, the file is placed at /local/path/path/symlink. Use --flat=true to place the file directly in the destination folder without intermediate directories.

  1. Run:
jf rt download <repository-key>/<artifact-path> <local-destination>/ --validate-symlinks=true --flat=true

Where:

  • <repository-key>/<artifact-path> β€” Repository key and path to the symlink artifact in JFrog Artifactory.
  • <local-destination> β€” Directory on your machine to receive the download.

Example:

jf rt download my-generic-repo/releases/link.so /tmp/restore/ --validate-symlinks=true --flat=true

Expected output:

{
  "status": "success",
  "totals": {
    "success": 1,
    "failure": 0
  }
}

If validation fails (for example, the target file no longer exists or has been modified), the symlink is excluded from the download. The CLI logs an [Error] message for each skipped symlink and exits with a non-zero exit code. No JSON summary is produced when validation fails; use the exit code to detect failure in scripts and CI pipelines.

Example failure output:

[Error] symlink validation failed for target: /path/to/target-file
[Error] download finished with errors, please review the logs
πŸ“˜

Trace ID on failure

On failure, the CLI also outputs a Trace ID, such as [Info] Trace ID for JFrog Platform logs: <id>. You can share this value with JFrog Support to correlate server-side logs.