Skip to content

[Bug]: Deletes in the share root always fail once with ENOENT (succeed on retry); rm -rf silently leaves the directory behind #263

Description

@aderaaij

Hi James, thanks for prolonging the life of my TImecapsule, and apologies for the AI bug report, but it can describe the issue more structured than I can (although maybe not more succinct).

Interface

Python CLI

Host system

macOS 26.5.2

Time Capsule model and generation

Gen 5 NetBSD 6 little-endian (A1470), firmware 7.9.1


Summary

Every unlink/rmdir of an object located directly in the share root fails on the first
attempt with ENOENT, then succeeds on an immediate retry. Deletes in any subdirectory work
correctly on the first attempt.

Because rm -rf passes -f, it swallows the ENOENT and exits 0 while leaving the directory in
place
, so the failure is silent.

Environment

TimeCapsuleSMB v2.2.9 (commit e6a405a)
Samba 4.24.3
Device AirPort Time Capsule 802.11ac gen 5 (A1470), syAP=119, firmware 7.9.1, NetBSD 6 LE
Client macOS 26.5.2, stock smbfs client, SMB 3.1.1
Share [Data], path = /Volumes/dk2/ShareRoot, mounted at /Volumes/Data-1

tcapsule doctor reports all checks passing. Time Machine backups to this share complete
successfully (RESULT = 0), so the share is otherwise healthy.

Reproduction

Mount the share, then:

SHARE=/Volumes/Data-1

# --- share root: fails ---
mkdir "$SHARE/testdir"
rmdir "$SHARE/testdir"        # rmdir: No such file or directory   <-- but it DOES exist
rmdir "$SHARE/testdir"        # succeeds

# --- silent variant ---
mkdir "$SHARE/testdir2"
rm -rf "$SHARE/testdir2"; echo "exit=$?"   # exit=0
ls -d "$SHARE/testdir2"                    # still there
rm -rf "$SHARE/testdir2"                   # now it is removed

# --- one level down: works ---
mkdir -p "$SHARE/sub"
mkdir "$SHARE/sub/testdir"
rmdir "$SHARE/sub/testdir"    # succeeds first time

Measured results

Each cell is "first-attempt failures / trials", captured via direct syscalls with errno:

Location Directories (rmdir) Files (unlink)
Share root 8/8 — ENOENT 8/8 — ENOENT
Depth 1 (root/sub/) 0/8 0/8
Depth 2 (root/sub/x/) 0/8 0/8

The retry always succeeds, and no leftovers remain afterwards.

Not a caching or timing artifact

Inserting a lookup or a delay between create and delete makes no difference (5 trials each):

Sequence (share root) First-attempt failures
mkdir; rmdir 5/5
mkdir; stat; rmdir 5/5
mkdir; ls parent; rmdir 5/5
mkdir; sleep 2; rmdir 5/5
touch; rm (file) 5/5
mkdir; rmdir in a subdirectory 0/5

Number of children in the directory is irrelevant — rm -rf leaves the directory behind 5/5 times
with 0, 1, 5, or 20 children.

Not a macOS client bug

Same macOS client, same session, other SMB servers on the same LAN (Synology DSM):

Share root First-attempt rmdir failures
//synology/data 0/6
//synology/backups 0/6
//timecapsule/Data 6/6 — ENOENT

Related issues (already ruled out)

  • SMB delete and rename operations fail over CIFS on Linux clients #14 — delete/rename failures from Linux CIFS clients: different error (EINVAL / NT_STATUS_INVALID_PARAMETER), fails on every attempt, at any depth. This report is a macOS client, ENOENT, first attempt only, share root only.
  • Copy and Delete from iPhone/iPad Photos app #170 — undeletable iOS Photos uploads: that was xattr EIO corruption on specific files regardless of location. Here xattrs read fine, the affected objects are plain open()/mkdir creations, and the retry always succeeds — so not the same xattr issue.

Also ruled out

  • macOS version — reproduces identically on 26.4 and 26.5.2
  • Device clock skew — reproduces with the device clock accurate to within ~3 s of the client
  • Extended attributes — reproduces on plain open()-created files with no xattrs, and on files
    with xattrs set
  • File vs directory — both affected equally
  • Objects created by smbclient rather than the macOS client delete correctly on the first attempt

Server log

Nothing is logged at the default level when the failing delete happens. log.smbd contains only
startup messages. Happy to re-run with log level raised if that would help.

Share configuration

[Data]
    path = /Volumes/dk2/ShareRoot
    browseable = yes
    read only = no
    guest ok = no
    valid users = root
    veto files = /.samba4/
    vfs objects = catia fruit streams_xattr acl_xattr xattr_tdb
    acl_xattr:ignore system acls = yes
    streams_xattr:max xattrs per stream = 2
    fruit:resource = file
    fruit:metadata = netatalk
    fruit:encoding = native
    fruit:time machine = yes
    fruit:posix_rename = yes
    xattr_tdb:file = /Volumes/dk2/.samba4/private/xattr.tdb
    force user = root
    force group = wheel
    create mask = 0666
    directory mask = 0777
    force create mode = 0666
    force directory mode = 0777

Relevant globals: fruit:delete_empty_adfiles = yes, fruit:veto_appledouble = yes,
fruit:wipe_intentionally_left_blank_rfork = yes, ea support = yes.

Speculation (unverified)

The share root is the only directory where veto files = /.samba4/ can match, and it is also the
only path where the fruit/xattr_tdb AppleDouble cleanup runs against the share's top level.
That is the one structural difference I can see between the failing and working cases, but I have
not instrumented the server to confirm it — treat this as a hint rather than a diagnosis.

Impact

Low for Time Machine, which is unaffected. The concern is that rm -rf reports success while
leaving directories behind, so a user cleaning up the share can reasonably believe a delete
happened when it did not.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions