
In Go, os.FileMode only controls file permissions (e.g., read/write/execute bits), not ownership — to set UID and GID, you must use os.Chown after file creation. There is no single-step API that combines mode + ownership in one call.
in go, `os.filemode` only controls file permissions (e.g., read/write/execute bits), not ownership — to set uid and gid, you must use `os.chown` *after* file creation. there is no single-step api that combines mode + ownership in one call.
File ownership (UID/GID) and permission bits are handled by separate system calls in Unix-like operating systems — and Go reflects this separation in its standard library. While os.FileMode (e.g., 0644, 0755) determines who can access the file and how, the numeric user and group identifiers are managed independently via the chown(2) system call — exposed in Go as os.Chown.
Here’s a complete, idiomatic example:
package main
import (
"os"
"fmt"
)
func createAndChown(filename string, uid, gid int) error {
// Step 1: Create file with desired permissions
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("failed to create file: %w", err)
}
defer f.Close()
// Step 2: Set ownership (UID/GID) — must be done after creation
if err := os.Chown(filename, uid, gid); err != nil {
return fmt.Errorf("failed to set ownership: %w", err)
}
fmt.Printf("Created %s with UID=%d, GID=%d, mode=0644\n", filename, uid, gid)
return nil
}
func main() {
// Example: assign to current user/group (replace with actual IDs as needed)
err := createAndChown("example.txt", 1001, 1001)
if err != nil {
panic(err)
}
}⚠️ Important Notes:
-
os.Chownrequires appropriate privileges: only root (or processes withCAP_CHOWN) can change UID/GID to arbitrary values. Non-root users can typically only change the group to one they belong to (if supported by the OS). - Always call
os.Chownafter the file exists — it fails on non-existent paths. - For directories,
os.Chownaffects only the directory itself, not its contents (recursive chown requires manual traversal). - Avoid hardcoding UID/GID numbers in production; prefer resolving them via
user.Lookuporuser.LookupGroupwhen names are known.
In summary: permissions → os.FileMode (at creation time); ownership → os.Chown (immediately after). There is no “one-step” method — and for good reason: it enforces clarity and aligns with POSIX semantics.

















