juicedata/juicefs · error

no quota for any trash directory

Error message

no quota for any trash directory

What it means

HandleQuota refuses to manage directory quotas on trash directories. Trash is system-managed and quotas on it are meaningless/unsupported, so any set/list-modifying quota command resolving to a trash inode is rejected with this error.

Source

Thrown at pkg/meta/quota.go:597

			m.updateQuota(q, snap.quota.newSpace, snap.quota.newInodes)
		}
	}
	m.quotaMu.Unlock()

}

func (m *baseMeta) HandleQuota(ctx Context, cmd uint8, qkey string, qtype uint32, quotas map[string]*Quota, strict, repair bool, create bool) error {
	var inode Ino
	var dpath string
	var key uint64

	if qtype == DirQuotaType && cmd != QuotaList {
		dpath = qkey
		if st := m.resolve(ctx, dpath, &inode, create); st != 0 {
			return fmt.Errorf("resolve dir %s: %s", dpath, st)
		}
		if inode.IsTrash() {
			return errors.New("no quota for any trash directory")
		}
		key = uint64(inode)
	} else if (qtype == UserQuotaType || qtype == GroupQuotaType) && cmd != QuotaCheck {
		id, err := strconv.ParseUint(qkey, 10, 64)
		if err != nil {
			return fmt.Errorf("parse quota key %q: %s", qkey, err)
		}
		key = id
	}

	switch cmd {
	case QuotaSet:
		return m.handleQuotaSet(ctx, qtype, key, dpath, quotas, strict)
	case QuotaGet:
		return m.handleQuotaGet(ctx, qtype, key, dpath, quotas)
	case QuotaDel:
		return m.en.doDelQuota(ctx, qtype, key)
	case QuotaList:

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Target a regular directory instead of a .trash path; quotas only apply to normal dirs, users, or groups.
  2. To control trash space, adjust trash retention (`juicefs trash` / format's TrashDays) rather than setting quotas.
  3. Update automation scripts to skip/exclude .trash when enumerating quota targets.

Example fix

// before
juicefs quota set /mnt/jfs/.trash/1-20240101 100G
// after
juicefs quota set /mnt/jfs/data 100G
Defensive patterns

Strategy: validation

Validate before calling

func isTrashPath(p string) bool {
	parts := strings.SplitN(filepath.ToSlash(p), "/.trash/", 2)
	return len(parts) == 2 || strings.HasSuffix(p, "/.trash")
}
// skip quota operations when isTrashPath(target)

Prevention

When it happens

Trigger: Running a quota command (set/delete/check other than list) whose target path is inside .trash (resolves to an inode with IsTrash() true), e.g. `juicefs quota set /jfs/.trash/... 10G`.

Common situations: Scripting quota automation that accidentally walks into .trash; users trying to cap trash growth — which is controlled by trash schedule/retention, not quotas.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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