juicedata/juicefs · error

failed to chtimes

Error message

failed to chtimes %s

What it means

objbench 'change mtime' test wraps an error from fi.Chtimes(key, mtime) — the FileSystem interface's change-times call — into 'failed to chtimes %s'. It means the benchmark could not set the object's modification time before verifying it via Head.

Solutions

  1. Inspect the wrapped error to find the Chtimes failure cause.
  2. Confirm the key exists (earlier objbench case created it); rerun the full benchmark.
  3. Use a backend that supports Chtimes / mtime metadata.
  4. Check write permissions on the target prefix.

Example fix

// before
return fmt.Errorf("failed to chtimes %s", err)
// after
return fmt.Errorf("failed to chtimes %s: %w", key, err)
Defensive patterns

Strategy: validation

Validate before calling

if _, err := blob.Head(ctx, key); err != nil {
    return fmt.Errorf("key %s not headable: %w", key, err)
}

Try / catch

if err := fi.Chtimes(key, mtime); err != nil {
    log.Warnf("chtimes unsupported or failed for %s: %v", key, err)
    return nil // degrade gracefully on backends without Chtimes
}

Prevention

When it happens

Trigger: Calling fi.Chtimes(key, mtime) with mtime = now -10min and the filesystem implementation returns an error (backend rejects Chtimes, key missing, permission issue).

Common situations: Backends whose objectStorage doesn't support setting mtime; key already removed by a failed previous case; running objbench against storage that errors on Chtimes.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at cmd/objbench.go:1131

	funFSCase("change permission", func() error {
		if err := fi.Chmod(key, 0777); err != nil {
			return err
		}
		if objInfo, err := blob.Head(ctx, key); err != nil {
			return fmt.Errorf("failed to head object %s", err)
		} else if info, ok := objInfo.(object.File); ok {
			if info.Mode()&0xFFF != 0777 {
				return fmt.Errorf("expect mode %o but got %o", 0777, info.Mode())
			}
		}
		return nil
	})

	funFSCase("change mtime", func() error {
		mtime := time.Now().Add(-10 * time.Minute)
		if err := fi.Chtimes(key, mtime); err != nil {
			return fmt.Errorf("failed to chtimes %s", err)
		}
		if objInfo, err := blob.Head(ctx, key); err != nil {
			return fmt.Errorf("failed to head object %s", err)
		} else {
			if objInfo.Mtime().Before(mtime.Add(-2*time.Second)) || objInfo.Mtime().After(mtime.Add(2*time.Second)) {
				return fmt.Errorf("mtime deviation is too large, the actual mtime is %s but got %s", mtime.Format(time.RFC3339), objInfo.Mtime().Format(time.RFC3339))
			}
		}
		return nil
	})
}

View on GitHub (pinned to c9a67b23e8)