juicedata/juicefs · warning
expect group %s but got %s
Error message
expect group %s but got %s
What it means
Verification failure in the same case: after Chown(key, "nobody", groupName), Head reports the object's Group does not equal groupName. The group part of the ownership change was not persisted or the metadata served is stale. Only checked when Head returns object.File metadata.
Source
Thrown at cmd/objbench.go:1108
}
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())
}
}
return nil
})View on GitHub (pinned to c9a67b23e8)
Solutions
- Confirm groupName exists on the storage side (getent group) and matches exactly (case-sensitive).
- Run as root so the group change is actually applied.
- Invalidate caches / re-Head after a short delay to rule out staleness.
- Skip the case for backends lacking group metadata support.
Defensive patterns
Strategy: type-guard
Validate before calling
if _, err := user.LookupGroup(groupName); err != nil {
return fmt.Errorf("group %s not resolvable: %w", groupName, err)
}
if objInfo, err := blob.Head(ctx, key); err == nil {
if _, ok := objInfo.(object.File); !ok {
return utils.ErrNotSUP
}
} Type guard
func asFile(o object.ObjectMetadata) (object.File, bool) {
f, ok := o.(object.File)
return f, ok
} Prevention
- Ensure the group name exists and matches exactly on the storage side
- Run with root privileges so group changes apply
- Re-Head after cache invalidation to avoid stale group info
- Skip group verification for backends without group metadata
When it happens
Trigger: fi.Chown succeeded but info.Group() != groupName on the follow-up Head: backend ignored the group change, groupName doesn't exist on the storage side, or stale metadata was returned.
Common situations: Groups not synced between the client host and the storage backend, FUSE/file backends where group changes need root, cached Head responses, backends mapping group names to IDs inconsistently.
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 owner nobody 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/f7f339e6e9ca1816.
Report an issue: GitHub.