Troubleshooting
This guide covers common issues and their solutions when working with DittoFS.
Table of Contents
Section titled “Table of Contents”- Connection Issues
- Mount Issues
- Permission Issues
- File Handle Issues
- Performance Issues
- Cross-Protocol Issues
- Logging and Debugging
Connection Issues
Section titled “Connection Issues”Cannot mount: Connection refused
Section titled “Cannot mount: Connection refused”Symptoms:
mount.nfs: Connection refusedSolutions:
-
Check if DittoFS is running:
Terminal window ps aux | grep dfs -
Verify the port is correct:
Terminal window netstat -an | grep 12049# orlsof -i :12049 -
Check firewall rules:
Terminal window # Linuxsudo iptables -L | grep 12049# macOSsudo pfctl -s rules | grep 12049 -
Verify configuration:
Terminal window # Check the config filecat ~/.config/dfs/config.yaml# Start with debug loggingDITTOFS_LOGGING_LEVEL=DEBUG ./dfs start
Connection timeout
Section titled “Connection timeout”Symptoms:
mount.nfs: Connection timed outSolutions:
-
Check network connectivity:
Terminal window ping localhosttelnet localhost 12049 -
Review timeout settings in config:
adapters:nfs:timeouts:read: 5mwrite: 30sidle: 5m
Mount Issues
Section titled “Mount Issues”Invalid file system
Section titled “Invalid file system”Symptoms:
mount: /mnt/nfs: invalid file system.Cause: The mount point directory does not exist.
Solution: Create the mount point before mounting:
# Linuxsudo mkdir -p /mnt/nfssudo mount -t nfs -o tcp,port=12049,mountport=12049 localhost:/export /mnt/nfs
# macOS (use /tmp since /mnt doesn't exist, sudo not required)mkdir -p /tmp/nfsmount -t nfs -o tcp,port=12049,mountport=12049 localhost:/export /tmp/nfsPermission denied when mounting
Section titled “Permission denied when mounting”Symptoms:
mount.nfs: access denied by server while mountingSolutions:
-
On Linux, allow non-privileged ports:
Terminal window sudo sysctl -w net.ipv4.ip_unprivileged_port_start=0 -
On macOS, use resvport option:
Terminal window sudo mount -t nfs -o tcp,port=12049,mountport=12049,resvport localhost:/export /mnt/test -
Check export configuration:
shares:- name: /exportallowed_clients:- 192.168.1.0/24 # Make sure your IP is in this rangedenied_clients: [] -
Verify authentication settings:
shares:- name: /exportrequire_auth: false # Set to false for developmentallowed_auth_methods: [anonymous, unix]
No such file or directory
Section titled “No such file or directory”Symptoms:
mount.nfs: mounting localhost:/export failed, reason given by server: No such file or directorySolutions:
-
Verify the export path exists in configuration:
shares:- name: /export # This is the export path -
Check share names are correct:
Terminal window # Mount using the exact share name from configsudo mount -t nfs -o nfsvers=3,tcp,port=12049,mountport=12049 localhost:/export /mnt/test
SMB mount permission denied (macOS)
Section titled “SMB mount permission denied (macOS)”Symptoms:
zsh: permission denied: /tmp/smb-test/file.txtThis happens after mounting an SMB share, even with 0777 permissions.
Cause: macOS has a security restriction where only the mount owner can access files, regardless of Unix permissions. This is enforced at a level below file permissions - no SMB traffic even reaches the server. Apple confirmed this is “works as intended”.
Solution - use dfsctl (handles this automatically):
The dfsctl share mount command automatically handles this by using sudo -u $SUDO_USER
to mount as your user instead of root:
# This works - mount owned by your user, not rootsudo dfsctl share mount --protocol smb /export /mnt/shareAlternative - mount to user directory without sudo:
mkdir -p ~/mnt/sharedfsctl share mount --protocol smb /export ~/mnt/shareIf using manual mount_smbfs:
# Mount as your user, not rootsudo -u $USER mount_smbfs //user:pass@localhost:12445/export /mnt/shareNote: This is a macOS-specific issue. On Linux, dfsctl share mount uses uid/gid
options which work correctly.
See Known Limitations for details.
Permission Issues
Section titled “Permission Issues”Permission denied on file operations
Section titled “Permission denied on file operations”Symptoms:
touch: cannot touch 'file.txt': Permission deniedSolutions:
-
Check identity mapping configuration:
shares:- name: /exportidentity_mapping:map_all_to_anonymous: true # Try this for developmentanonymous_uid: 65534anonymous_gid: 65534 -
Verify root directory permissions:
shares:- name: /exportroot_attr:mode: 0777 # Wide open for debugginguid: 0gid: 0 -
Check your client UID/GID:
Terminal window id # Check your UID and GID -
Enable debug logging to see auth context:
Terminal window DITTOFS_LOGGING_LEVEL=DEBUG ./dfs start# Look for lines showing UID/GID in requests
Read-only filesystem
Section titled “Read-only filesystem”Symptoms:
touch: cannot touch 'file.txt': Read-only file systemSolutions:
-
Check share configuration:
shares:- name: /exportread_only: false # Must be false for writes -
Verify mount options:
Terminal window # Make sure you're not mounting with 'ro'sudo mount -t nfs -o nfsvers=3,tcp,port=12049,mountport=12049,rw localhost:/export /mnt/test
File Handle Issues
Section titled “File Handle Issues”Stale file handle
Section titled “Stale file handle”Symptoms:
ls: cannot access 'file.txt': Stale file handleCauses:
- Server was restarted with in-memory metadata (handles lost)
- File was deleted while client held a handle
- Metadata backend was changed
Solutions:
-
Unmount and remount the filesystem:
Terminal window sudo umount /mnt/testsudo mount -t nfs -o nfsvers=3,tcp,port=12049,mountport=12049 localhost:/export /mnt/test -
For persistent handles, use BadgerDB metadata:
Terminal window ./dfsctl store metadata add --name persistent --type badger \--config '{"path":"/var/lib/dfs/metadata"}'./dfsctl store block add --kind local --name default --type memory./dfsctl share create --name /export --metadata persistent --local default -
Clear client NFS cache (Linux):
Terminal window # This varies by distributionsudo service nfs-common restart
Performance Issues
Section titled “Performance Issues”Slow read/write operations
Section titled “Slow read/write operations”Diagnostics:
# Run benchmarks to identify bottleneck./scripts/benchmark.sh --profile
# Check server logs for slow operationstail -f ~/.config/dfs/dfs.log | grep -i "slow\|timeout"Solutions:
-
Tune buffer sizes:
metadata:global:filesystem_capabilities:max_read_size: 1048576 # 1MBmax_write_size: 1048576 # 1MB -
Use memory stores for development:
Terminal window ./dfsctl store metadata add --name fast --type memory./dfsctl store block local add --name fast --type memory -
For S3, verify configuration:
Terminal window ./dfsctl store block remote add --name s3-store --type s3 \--config '{"region":"us-east-1","bucket":"my-bucket"}'
High memory usage
Section titled “High memory usage”Diagnostics:
# Profile memory usagego test -bench=. -memprofile=mem.prof ./test/e2e/go tool pprof mem.profSolutions:
-
Check for memory leaks in logs
-
Reduce max connections:
adapters:nfs:max_connections: 100 -
Monitor metrics:
server:metrics:enabled: trueport: 9090Then visit
http://localhost:9090/metrics
Logging and Debugging
Section titled “Logging and Debugging”Enable Debug Logging
Section titled “Enable Debug Logging”Via environment variable:
DITTOFS_LOGGING_LEVEL=DEBUG ./dfs startVia configuration:
logging: level: DEBUG format: text # or json output: stdout # or file pathUnderstanding Log Output
Section titled “Understanding Log Output”Key log patterns:
[INFO] NFS: Accepted connection from 127.0.0.1:54321- Client connected[DEBUG] NFS: LOOKUP(handle=..., name=file.txt)- Operation details[ERROR] NFS: Failed to read file: no such file- Error conditions[DEBUG] Auth: UID=1000, GID=1000, GIDs=[1000,4,20]- Authentication context
Capture Traffic
Section titled “Capture Traffic”For deep debugging, capture NFS traffic:
# Linuxsudo tcpdump -i lo -w nfs.pcap port 12049
# macOSsudo tcpdump -i lo0 -w nfs.pcap port 12049
# Analyze with Wiresharkwireshark nfs.pcapCheck Server Health
Section titled “Check Server Health”# Check if server is responding./dfs status
# Check metrics (if enabled)curl http://localhost:9090/metrics
# Check configurationDITTOFS_LOGGING_LEVEL=DEBUG ./dfs start 2>&1 | grep -i "config"Cross-Protocol Issues
Section titled “Cross-Protocol Issues”When running both NFS and SMB adapters simultaneously, the shared LockManager coordinates caching state between protocols. This section covers common cross-protocol issues and their resolution.
File Locked by Another Protocol
Section titled “File Locked by Another Protocol”Symptoms:
NFS: NFS4ERR_SHARE_DENIED or NFS4ERR_LOCKEDSMB: STATUS_SHARING_VIOLATION or STATUS_LOCK_NOT_GRANTEDCause: An SMB client holds an exclusive lease (RWH) or byte-range lock on a file that an NFS client is trying to access, or vice versa.
Diagnosis:
# Check active locks and leases via debug loggingDITTOFS_LOGGING_LEVEL=DEBUG ./dfs start# Look for log entries containing:# "cross_protocol_break" - Break initiated across protocols# "lease_break" - SMB lease being broken# "delegation_recall" - NFS delegation being recalledResolution:
- Wait for the lease/delegation break to complete (the LockManager automatically initiates breaks)
- If the break times out (35s for SMB leases, 90s for NFS delegations), the server force-revokes and the operation proceeds
- Check if the client holding the lock is still connected
Delegation Recall Timeouts
Section titled “Delegation Recall Timeouts”Symptoms:
[WARN] delegation recall timeout: delegID=abc123 client=nfs-client elapsed=90sCause: An NFS client did not respond to a CB_RECALL (callback recall) within the configured timeout (default 90 seconds). This happens when:
- The NFS client is unresponsive or has network issues
- The NFS client’s backchannel is broken
- The CB_RECALL message was lost
Resolution:
- After timeout, the delegation is force-revoked and the conflicting operation proceeds
- Check NFS client connectivity and backchannel health
- Adjust timeout if needed:
adapters:smb:cross_protocol:delegation_recall_timeout: 120s # Increase from 90s default
- Enable debug logging to see the recall flow:
Terminal window DITTOFS_LOGGING_LEVEL=DEBUG ./dfs start 2>&1 | grep "delegation"
Lease Break Storms
Section titled “Lease Break Storms”Symptoms:
[INFO] cross_protocol_break: file=/export/data.bin protocol=smb->nfs type=lease_break count=47 period=60sRapid grant-break-grant-break cycles visible in logs.
Cause: Two clients (one NFS, one SMB) are alternately opening the same file with conflicting access modes, causing the LockManager to repeatedly break and re-grant caching state.
Resolution:
- DittoFS has a built-in anti-storm cache (default 30-second TTL) that prevents re-grants after a break
- If storms persist, increase the anti-storm TTL:
adapters:smb:cross_protocol:anti_storm_ttl: 60s # Increase from 30s default
- Consider configuring the conflicting clients to use the same protocol for the shared file
- Read-only access from both protocols does not cause storms (NFS read delegation + SMB Read lease coexist)
SMB Client Cannot Write to NFS-Delegated File
Section titled “SMB Client Cannot Write to NFS-Delegated File”Symptoms:
- SMB WRITE or CREATE (write access) hangs for several seconds before succeeding
- Or fails with STATUS_SHARING_VIOLATION
Cause: An NFS client holds a write delegation on the file. The LockManager must recall the delegation via CB_RECALL and wait for the NFS client to return it before the SMB write can proceed.
Expected behavior: This is correct cross-protocol coordination. The delay is the delegation recall round-trip time (typically under 1 second for responsive NFS clients, up to 90 seconds for the timeout).
Resolution:
- This is normal behavior — the SMB write will succeed once the NFS delegation is returned
- If the delay is unacceptable, disable delegations for the share (reduces NFS performance)
- Monitor recall latency in debug logs
NFS Client Sees Stale Data After SMB Write
Section titled “NFS Client Sees Stale Data After SMB Write”Symptoms:
- NFS client reads file and gets old content after an SMB client has written new content
Cause: The NFS client cached the file data under a read delegation, and the delegation recall + cache invalidation has not completed yet.
Resolution:
- DittoFS automatically sends CB_RECALL to NFS clients when an SMB client modifies a file
- After the recall, the NFS client invalidates its cache and re-reads from the server
- If the NFS client is not responding to recalls:
- Check NFS client backchannel connectivity
- After delegation recall timeout (90s), the delegation is force-revoked
- NFS client’s next request will fail with EXPIRED or ADMIN_REVOKED, forcing a refresh
- Force a cache refresh on the NFS client:
Terminal window # Remount with noac to disable attribute cachingsudo mount -t nfs4 -o noac server:/export /mnt/nfs
Directory Listing Inconsistency Across Protocols
Section titled “Directory Listing Inconsistency Across Protocols”Symptoms:
- Creating a file via SMB, but NFS
lsdoes not show it (or vice versa)
Cause: Directory change notifications have not yet broken the other protocol’s directory lease/delegation.
Resolution:
- DittoFS automatically breaks directory leases and delegations when
CreateFile,RemoveFile, orRenamemodifies a directory - The break is processed through the LockManager and dispatched to both protocols
- If inconsistency persists:
- Verify directory leases are enabled: check
leases.directory_leases: true - Check for notification queue overflow (1024 events/directory capacity)
- Force a directory re-read:
ls -la /mnt/nfs/dir/or refresh the SMB directory listing
- Verify directory leases are enabled: check
Diagnostic Commands
Section titled “Diagnostic Commands”# Enable cross-protocol debug loggingDITTOFS_LOGGING_LEVEL=DEBUG ./dfs start
# Key log patterns to search for:# "cross_protocol_break" - Break initiated between protocols# "delegation_recall" - NFS delegation being recalled# "lease_break" - SMB lease being broken# "anti_storm" - Grant suppressed by anti-storm cache# "dir_change_notify" - Directory change notification dispatched# "break_timeout" - Break acknowledgment timed outLog Messages Reference
Section titled “Log Messages Reference”| Log Message | Level | Meaning |
|---|---|---|
cross_protocol_break | INFO | A caching break was initiated across protocols |
delegation_recall | DEBUG | CB_RECALL sent to NFS client |
delegation_returned | DEBUG | NFS client returned delegation voluntarily |
delegation_force_revoked | WARN | Delegation revoked after timeout |
lease_break | DEBUG | Lease break notification sent to SMB client |
lease_break_ack | DEBUG | SMB client acknowledged lease break |
anti_storm_suppressed | DEBUG | Grant suppressed by anti-storm cache |
dir_change_notify | DEBUG | Directory change event queued |
notification_overflow | WARN | Directory notification queue overflowed |
Common Error Messages
Section titled “Common Error Messages””export not found”
Section titled “”export not found””Cause: The share name in the mount command doesn’t match configuration.
Solution: Check share names in config and use exact match:
# If config has "name: /export"sudo mount -t nfs -o nfsvers=3,tcp,port=12049,mountport=12049 localhost:/export /mnt/test“authentication failed”
Section titled ““authentication failed””Cause: Server requires authentication but client isn’t providing it.
Solution: Either disable authentication or configure it properly:
shares: - name: /export require_auth: false allowed_auth_methods: [anonymous, unix]“metadata store not found”
Section titled ““metadata store not found””Cause: Share references a non-existent metadata store.
Solution: Ensure stores exist before creating the share:
# Create the stores first./dfsctl store metadata add --name my-store --type memory./dfsctl store block local add --name my-blocks --type memory
# Then create the share referencing them./dfsctl share create --name /export --metadata my-store --local my-blocksNFSv4 Session Issues
Section titled “NFSv4 Session Issues”Client cannot establish NFSv4 session
Section titled “Client cannot establish NFSv4 session”Symptoms:
mount.nfs4: Protocol not supportedSolutions:
- Verify NFSv4 is enabled in the adapter settings:
Terminal window dfsctl adapter settings nfs - Check that the client supports NFSv4. Some older clients default to NFSv3.
- Try mounting with explicit version:
Terminal window sudo mount -t nfs4 localhost:/export /mnt/test
Session expired or lost
Section titled “Session expired or lost”Symptoms:
NFS4ERR_EXPIRED or NFS4ERR_STALE_CLIENTIDSolutions:
- The server may have restarted, causing session loss. Remount the share.
- Check the grace period status:
Terminal window dfsctl grace status - If in grace period, wait for it to complete before retrying.
Kerberos Authentication Issues
Section titled “Kerberos Authentication Issues”Kerberos authentication fails
Section titled “Kerberos authentication fails”Symptoms:
mount.nfs4: access denied by serverwith RPCSEC_GSS configured.
Solutions:
- Verify the keytab file is accessible:
Terminal window klist -k /etc/krb5.keytab - Check that the service principal matches the server hostname
- Verify clock synchronization between client and KDC (Kerberos requires clocks within 5 minutes)
- Enable debug logging to see the RPCSEC_GSS negotiation:
Terminal window DITTOFS_LOGGING_LEVEL=DEBUG ./dfs start
ACL Issues
Section titled “ACL Issues”ACL operations fail with NFS3ERR_NOTSUPP
Section titled “ACL operations fail with NFS3ERR_NOTSUPP”Symptoms:
setfacl: Operation not supportedSolutions:
- ACLs require NFSv4. Ensure you are mounting with NFSv4:
Terminal window sudo mount -t nfs4 localhost:/export /mnt/test - NFSv3 does not support ACLs - only standard POSIX mode bits.
Getting More Help
Section titled “Getting More Help”If you’re still experiencing issues:
- Check existing issues: GitHub Issues
- Enable debug logging and capture relevant output
- Open a new issue with:
- DittoFS version
- Operating system and version
- Configuration file (redact sensitive info)
- Full error messages
- Debug logs showing the problem
- Steps to reproduce