juicedata/juicefs · error

mkdir %s

Error message

mkdir %s

What it means

This error comes from nfsStore.Symlink in pkg/object/nfs.go:424. When creating a symlink whose parent directory does not yet exist, the store first attempts to Mkdir that parent; if Mkdir fails with an error that is not os.ErrExist (e.g. permission denied, I/O error on the NFS mount), the mkdir failure is wrapped with the target directory path and returned. It is a wrapper, so the root cause (the underlying syscall error) is in the wrapped chain.

Source

Thrown at pkg/object/nfs.go:424

			UID: nfs.SetUID{
				SetIt: true,
				UID:   uint32(uid),
			},
			GID: nfs.SetUID{
				SetIt: true,
				UID:   uint32(gid),
			},
		}
	})
}

func (n *nfsStore) Symlink(oldName, newName string) error {
	newName = strings.TrimRight(newName, "/")
	p := n.path(newName)
	dir := path.Dir(p)
	if _, _, err := n.target.Lookup(dir); err != nil && os.IsNotExist(err) {
		if _, err := n.target.Mkdir(dir, n.dmode); err != nil && !os.IsExist(err) {
			return errors.Wrapf(err, "mkdir %s", dir)
		}
	} else if err != nil && !os.IsNotExist(err) {
		return err
	}
	return n.target.Symlink(n.path(oldName), n.path(newName))
}

func (n *nfsStore) Readlink(name string) (string, error) {
	f, err := n.target.Open(n.path(name))
	if err != nil {
		return "", errors.Wrapf(err, "open %s", name)
	}
	return f.Readlink()
}

func (n *nfsStore) ListAll(ctx context.Context, prefix, marker string, followLink bool) (<-chan Object, error) {
	return nil, notSupported
}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Check permissions on the parent path of the target name on the NFS mount; ensure the process user can mkdir there (check /etc/exports squash options).
  2. Verify the NFS mount is not read-only (mount | grep nfs; remount rw if needed).
  3. Pre-create the parent directory manually with the correct ownership, then retry the operation.
  4. Inspect the wrapped root-cause error in the message chain to fix the underlying syscall problem.

Example fix

// before (fails: parent dir missing, cannot be created)
store.Symlink("/data/target", "/mnt/nfs/dir/sub/link")

// after: ensure parent exists and is writable first
os.MkdirAll("/mnt/nfs/dir/sub", 0o755)
store.Symlink("/data/target", "/mnt/nfs/dir/sub/link")
Defensive patterns

Strategy: try-catch

Validate before calling

p := "/mnt/nfs/dir/sub"
if _, err := os.Stat(p); err != nil {
    if err := os.MkdirAll(p, 0o755); err != nil {
        return fmt.Errorf("cannot create parent dir %s: %w", p, err)
    }
}
// also verify writability
if err := unix.Access(p, unix.W_OK); err != nil { return err }

Try / catch

err := store.Symlink(old, new)
if err != nil {
    var pe *os.PathError
    if errors.As(err, &pe) && (errors.Is(err, syscall.EACCES) || errors.Is(err, syscall.EROFS)) {
        // fix permissions / remount rw, then retry
    }
    return err
}

Prevention

When it happens

Trigger: Calling Symlink(oldName, newName) on an NFS-backed object store where path.Dir(newName) does not exist AND the automatic Mkdir of that parent fails with a non-IsExist error (e.g. EACCES, EROFS, EIO on the NFS export).

Common situations: NFS export mounted read-only or with squashed permissions (root_squash), so the JuiceFS process cannot create intermediate directories; network/permission issues on the underlying target filesystem when writing via the NFS object-store backend.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/3609a58071e24a4f. Report an issue: GitHub.