{"record":{"id":"9fe02a2fe6f61bf7","repo":"caddyserver/caddy","slug":"unable-to-set-permissions-s-on-s-v","errorCode":null,"errorMessage":"unable to set permissions (%s) on %s: %v","messagePattern":"unable to set permissions \\((.+?)\\) on (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"listeners.go","lineNumber":199,"sourceCode":"\t\t\tlnKey := listenerKey(na.Network, address)\n\t\t\tln, err = listenReusable(ctx, lnKey, na.Network, address, config)\n\t\t}\n\t}\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif ln == nil {\n\t\treturn nil, fmt.Errorf(\"unsupported network type: %s\", na.Network)\n\t}\n\n\tif IsUnixNetwork(na.Network) {\n\t\tisAbstractUnixSocket := strings.HasPrefix(address, \"@\")\n\t\tif !isAbstractUnixSocket {\n\t\t\terr = os.Chmod(address, unixFileMode)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"unable to set permissions (%s) on %s: %v\", unixFileMode, address, err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ln, nil\n}\n\n// IsUnixNetwork returns true if na.Network is\n// unix, unixgram, or unixpacket.\nfunc (na NetworkAddress) IsUnixNetwork() bool {\n\treturn IsUnixNetwork(na.Network)\n}\n\n// IsFdNetwork returns true if na.Network is\n// fd or fdgram.\nfunc (na NetworkAddress) IsFdNetwork() bool {\n\treturn IsFdNetwork(na.Network)\n}","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/listeners.go#L181-L217","documentation":"After creating a unix (non-abstract) listener, Caddy applies the configured permission bits with os.Chmod on the socket path. This error wraps a chmod failure: the path disappeared, the process lacks ownership/chmod rights, or the filesystem rejected the operation.","triggerScenarios":"Unix socket at a path the Caddy user cannot chmod (root-owned dir where the socket was created by another user), the socket file removed between bind and chmod by a cleanup race, or a filesystem that does not permit chmod (some network/ephemeral mounts).","commonSituations":"Running Caddy as non-root writing into /run without RuntimeDirectory; a second process deleting the socket concurrently; unusual container volumes mounted with restricted options.","solutions":["Ensure the Caddy process user owns or can chmod the socket path (systemd RuntimeDirectory=/run/caddy).","Remove stale socket files before start or enable Caddy's unix socket reuse.","Move the socket to a directory the service fully controls."],"exampleFix":"# before: /run owned by root, caddy runs as caddy\nlisten unix/run/caddy.sock\n# after (systemd unit)\n[Service]\nRuntimeDirectory=caddy\nlisten unix/run/caddy/caddy.sock","handlingStrategy":"validation","validationCode":"func canChmod(path string) bool {\n    info, err := os.Stat(path)\n    return err == nil && info.Mode().IsRegular() == false || err == nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run Caddy with a dedicated RuntimeDirectory so it owns the socket path.","Clean stale socket files before bind in service pre-start hooks."],"tags":["unix-socket","permissions","filesystem","listen"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}