juicedata/juicefs · warning
expect owner nobody but got %s
Error message
expect owner nobody but got %s
What it means
Verification failure in the 'change owner/group' case: after Chown to 'nobody', Head reports the object's Owner is still not 'nobody'. This means the ownership change did not take effect (silently ignored by the backend) or the metadata read is stale. It only fires when the object metadata is of type object.File (backends without File metadata skip the check).
Source
Thrown at cmd/objbench.go:1105
return fmt.Errorf("the content of the multipart upload file is incorrect")
}
return nil
}
return utils.ErrNotSUP
})
funFSCase("change owner/group", func() error {
if (strings.HasPrefix(blob.String(), "file://") || strings.HasPrefix(blob.String(), "jfs://")) && os.Getuid() != 0 {
return errors.New("root required")
}
if err := fi.Chown(key, "nobody", groupName); err != nil {
return fmt.Errorf("failed to chown object %s", 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.Owner() != "nobody" {
return fmt.Errorf("expect owner nobody but got %s", info.Owner())
}
if info.Group() != groupName {
return fmt.Errorf("expect group %s but got %s", groupName, info.Group())
}
}
return nil
})
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())
}View on GitHub (pinned to c9a67b23e8)
Solutions
- Verify the backend actually persists chown (test manually with `chown` + `ls -l`).
- Run as root — non-root chown may be silently dropped or fail in ways the check exposes.
- Invalidate/disable metadata caches between Chown and Head.
- Skip the ownership case for backends that don't support owner metadata.
Defensive patterns
Strategy: type-guard
Validate before calling
if objInfo, err := blob.Head(ctx, key); err == nil {
if _, ok := objInfo.(object.File); !ok {
return utils.ErrNotSUP // backend has no owner metadata to verify
}
} Type guard
func asFile(o object.ObjectMetadata) (object.File, bool) {
f, ok := o.(object.File)
return f, ok
} Prevention
- Only assert ownership on backends returning object.File metadata
- Run as root so chown actually persists
- Invalidate caches between Chown and Head
- Manually verify backend persists owner changes before relying on it
When it happens
Trigger: fi.Chown succeeded but info.Owner() != "nobody" in the subsequent Head: the backend accepted but ignored the chown, ownership mapping is not persisted, or a stale/cached metadata response was returned.
Common situations: Backends that emulate File metadata but don't persist owner changes, FUSE mounts where only root can chown yet the call silently no-ops, cached Head results on gateway/proxy layers.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- expect group %s but got %s
- Invalid parameter
- Invalid ACL: multiple entries with same scope, type and name
- Invalid ACL: this entry type must not have a name: " + entry
- get inode of %s: %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/19c1ede1296cd1e5.
Report an issue: GitHub.