{"record":{"id":"65f2d066c5a84af8","repo":"caddyserver/caddy","slug":"could-not-parse-octal-permission-bits-in-s-v","errorCode":null,"errorMessage":"could not parse octal permission bits in %s: %v","messagePattern":"could not parse octal permission bits in (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sockets.go","lineNumber":41,"sourceCode":"\n// SplitUnixSocketPermissionsBits takes a unix socket address in the\n// unusual \"path|bits\" format (e.g. /run/caddy.sock|0222) and tries\n// to split it into socket path (host) and permissions bits (port).\n// Colons (\":\") can't be used as separator, as socket paths on Windows\n// may include a drive letter (e.g. `unix/c:\\absolute\\path.sock`).\n// Permission bits will default to 0200 if none are specified.\n// Throws an error, if the first carrying bit does not\n// include write perms (e.g. `0422` or `022`).\n// Symbolic permission representation (e.g. `u=w,g=w,o=w`)\n// is not supported and will throw an error for now!\nfunc SplitUnixSocketPermissionsBits(addr string) (path string, fileMode fs.FileMode, err error) {\n\taddrSplit := strings.SplitN(addr, \"|\", 2)\n\n\tif len(addrSplit) == 2 {\n\t\t// parse octal permission bit string as uint32\n\t\tfileModeUInt64, err := strconv.ParseUint(addrSplit[1], 8, 32)\n\t\tif err != nil {\n\t\t\treturn \"\", 0, fmt.Errorf(\"could not parse octal permission bits in %s: %v\", addr, err)\n\t\t}\n\t\tfileMode = fs.FileMode(fileModeUInt64)\n\n\t\t// FileMode.String() returns a string like `-rwxr-xr--` for `u=rwx,g=rx,o=r` (`0754`)\n\t\tif string(fileMode.String()[2]) != \"w\" {\n\t\t\treturn \"\", 0, fmt.Errorf(\"owner of the socket requires '-w-' (write, octal: '2') permissions at least; got '%s' in %s\", fileMode.String()[1:4], addr)\n\t\t}\n\n\t\treturn addrSplit[0], fileMode, nil\n\t}\n\n\t// default to 0200 (symbolic: `u=w,g=,o=`)\n\t// if no permission bits are specified\n\treturn addr, 0o200, nil\n}\n","sourceCodeStart":23,"sourceCodeEnd":57,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/internal/sockets.go#L23-L57","documentation":"Caddy's SplitUnixSocketPermissionsBits splits a unix socket address of the form 'path|mode' (e.g. '/run/caddy.sock|0600'). The part after '|' must be a valid octal number no larger than 32 bits. If strconv.ParseUint with base 8 fails, this error is returned, wrapping the underlying parse error.","triggerScenarios":"Calling caddy.ParseNetworkAddress / listening on a unix address whose '|' suffix is not pure octal digits: 'u=rw,g=r' (symbolic modes are explicitly unsupported), '0x600' (hex prefix), '600 ' (trailing space), '77777777777' (exceeds 32-bit range), or an empty suffix like 'path|'.","commonSituations":"Users coming from chmod syntax write symbolic permissions ('u=rw') in the Caddyfile listen address. Others paste a decimal or hex mode, or a stray pipe character appears in the path. CI configs with templated modes often inject whitespace or an empty variable next to the '|'.","solutions":["Use 3-4 octal digits after the pipe, e.g. '/run/caddy.sock|0600'.","Remove the '|suffix' entirely to accept the default 0200 owner-write mode.","If you need symbolic permissions, translate them to octal first (u=rw,g= -> 0260 style mapping) in your config generation, since symbolic input is not supported.","Check for stray '|' characters or unexpanded variables in the address string."],"exampleFix":"// before\nunix/u=rw,g=r/run/caddy.sock\n// after (symbolic not supported; octal only)\nunix/run/caddy.sock|0640","handlingStrategy":"validation","validationCode":"func validOctalSuffix(addr string) bool {\n    parts := strings.SplitN(addr, \"|\", 2)\n    if len(parts) != 2 {\n        return true // no suffix; default 0200 applies\n    }\n    n, err := strconv.ParseUint(parts[1], 8, 32)\n    return err == nil && n <= 0o7777\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate socket permission suffixes from an integer formatted with %04o, never from user text.","Reject symbolic mode strings (u=,g=) in config validation upstream.","Prefer omitting the suffix unless you need non-default sharing."],"tags":["unix-socket","permissions","config","caddyfile"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}