In-depth Analysis and Solutions for rsync 'failed to set times' Error

Nov 23, 2025 · Programming · 7 views · 7.8

Keywords: rsync | file synchronization | permission error | timestamp setting | NFS filesystem

Abstract: This paper provides a comprehensive analysis of the 'failed to set times' error encountered during rsync file synchronization operations. It explores the root causes in special filesystems like NFS and FUSE, examines underlying permission mechanisms through code examples, and presents practical solutions using --omit-dir-times parameter, while discussing supplementary approaches for file ownership and system permissions.

Error Phenomenon and Background Analysis

When using rsync for file synchronization, users frequently encounter the following error message:

rsync: failed to set times on "/foo/bar": Operation not permitted (1)
rsync error: some files could not be transferred (code 23) 
  at /SourceCache/rsync/rsync-35.2/rsync/main.c(992) [sender=2.6.9]

While this error doesn't completely halt the file transfer process, it generates distracting messages in logs and affects operational cleanliness. The error indicates that permission was denied when attempting to set directory timestamps.

Root Cause Investigation

The core issue lies in the characteristics and permission restrictions of the target filesystem. When the target directory resides on NFS (Network File System) or certain FUSE (Filesystem in Userspace) implementations, these filesystems may impose additional restrictions on timestamp modification operations.

In Unix-like systems, setting file timestamps is typically accomplished through utime() or utimes() system calls. These system calls require the calling process to have appropriate privileges: either be the file owner or possess superuser privileges. Here's a simplified permission checking code example:

int set_file_times(const char *path, struct timespec *times) {
    struct stat st;
    
    // Retrieve file status information
    if (stat(path, &st) == -1) {
        return -1;
    }
    
    // Check permissions: current user must be file owner or root
    if (geteuid() != st.st_uid && geteuid() != 0) {
        errno = EPERM;  // Operation not permitted
        return -1;
    }
    
    // Execute timestamp setting
    return utimensat(AT_FDCWD, path, times, 0);
}

Solution Implementation

The most direct and effective solution for this problem is using rsync's --omit-dir-times option (or its shorthand -O). This option instructs rsync to skip setting directory timestamps, thereby avoiding permission checks.

Here's an example command using this option:

rsync -av --omit-dir-times /source/path/ user@remotehost:/target/path/

From the perspective of rsync source code, the implementation logic for this option大致如下:

// Relevant logic in timestamp setting function
void set_file_attrs(const char *path, struct file_struct *file, int flags) {
    // Check if omit_dir_times option is enabled
    if ((flags & ATTRS_SKIP_MTIME) || 
        (S_ISDIR(file->mode) && omit_dir_times)) {
        // Skip directory timestamp setting
        return;
    }
    
    // Normal timestamp setting logic
    if (set_modtime(path, file->modtime) < 0) {
        // Handle setting failure
        rprintf(FERROR, "failed to set times on %s: %s\n", 
                path, strerror(errno));
    }
}

Supplementary Analysis and Alternative Approaches

Beyond the primary solution, file ownership issues are another common cause of this error. Particularly on remote Darwin (macOS) systems, if the target directory ownership doesn't match the user executing the rsync process, permission errors will occur.

In such cases, file ownership can be checked and corrected as follows:

# Check file ownership
ls -la /foo/bar

# Correct ownership (if needed)
chown username:groupname /foo/bar

From a system call perspective, Darwin's utime() function implementation follows POSIX standards, requiring the calling process's effective user ID to match the file's owner ID or be the superuser. This design ensures system security but can sometimes inconvenience file synchronization operations.

Practical Application Recommendations

In actual production environments, it's recommended to choose appropriate solutions based on specific use cases:

  1. For NFS or FUSE filesystems: Prioritize using the --omit-dir-times option, as it's the safest and most reliable solution.
  2. For ownership issues: Ensure remote directories have correct ownership settings, or execute rsync operations with users possessing appropriate privileges.
  3. For automated scripts: Add error handling logic to properly log and ignore such non-fatal errors.

Here's a complete rsync wrapper script example demonstrating graceful handling of such errors:

#!/bin/bash

SOURCE_DIR="$1"
TARGET_DIR="$2"

# Execute rsync, ignoring directory timestamp errors
rsync -av --omit-dir-times "$SOURCE_DIR" "$TARGET_DIR" 2>&1 | \
    grep -v "failed to set times"

# Check exit status
if [ ${PIPESTATUS[0]} -eq 0 ] || [ ${PIPESTATUS[0]} -eq 23 ]; then
    echo "Synchronization completed (timestamp errors ignored)"
    exit 0
else
    echo "Synchronization failed"
    exit 1
fi

By deeply understanding rsync's working principles and system permission mechanisms, we can more effectively diagnose and resolve such permission issues in file synchronization, ensuring smooth data transfer operations.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.