{"record":{"id":"38d759a4a9a3c40f","repo":"caddyserver/caddy","slug":"invalid-file-descriptor-v-38d759","errorCode":null,"errorMessage":"invalid file descriptor: %v","messagePattern":"invalid file descriptor: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"listen_unix.go","lineNumber":109,"sourceCode":"}\n\n// listenReusable creates a new listener for the given network and address, and adds it to listenerPool.\nfunc listenReusable(ctx context.Context, lnKey string, network, address string, config net.ListenConfig) (any, error) {\n\t// even though SO_REUSEPORT lets us bind the socket multiple times,\n\t// we still put it in the listenerPool so we can count how many\n\t// configs are using this socket; necessary to ensure we can know\n\t// whether to enforce shutdown delays, for example (see #5393).\n\tvar (\n\t\tln         io.Closer\n\t\terr        error\n\t\tsocketFile *os.File\n\t)\n\n\tfd := slices.Contains([]string{\"fd\", \"fdgram\"}, network)\n\tif fd {\n\t\tsocketFd, err := strconv.ParseUint(address, 0, strconv.IntSize)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid file descriptor: %v\", err)\n\t\t}\n\n\t\tfunc() {\n\t\t\tsocketFilesMu.Lock()\n\t\t\tdefer socketFilesMu.Unlock()\n\n\t\t\tsocketFdWide := uintptr(socketFd)\n\t\t\tvar ok bool\n\n\t\t\tsocketFile, ok = socketFiles[socketFdWide]\n\n\t\t\tif !ok {\n\t\t\t\tsocketFile = os.NewFile(socketFdWide, lnKey)\n\t\t\t\tif socketFile != nil {\n\t\t\t\t\tsocketFiles[socketFdWide] = socketFile\n\t\t\t\t}\n\t\t\t}\n\t\t}()","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/listen_unix.go#L91-L127","documentation":"Unix-platform twin of the listen.go path: for network 'fd' or 'fdgram', the address must parse as an unsigned integer (base 0, int-sized). This error wraps the ParseUint failure — the address given for a file-descriptor listener is not a number.","triggerScenarios":"listen directives like 'listen fd /path/to/socket' (path instead of number), 'listen fd fd:3', empty address, or a number exceeding platform int size on Linux/macOS/BSD.","commonSituations":"Converting a unix-listen config to fd-based socket activation and leaving the path; templating that emits 'stdin' or a label where the fd number belongs.","solutions":["Provide the bare descriptor number as the address for the fd network.","Keep unix paths under the 'unix' network, not 'fd'.","Validate generated configs render the fd placeholder as an integer before deploy."],"exampleFix":"// before\nlisten fd /run/caddy.sock\n// after\nlisten fd 3","handlingStrategy":"validation","validationCode":"func isFdNetwork(network string) bool { return network == \"fd\" || network == \"fdgram\" }\n\n// before calling Listen:\n// if isFdNetwork(na.Network) { ensure address is strconv-able }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Unit-test config builders asserting fd addresses match ^[0-9]+$.","Document fd semantics for operators editing the config."],"tags":["file-descriptor","socket-activation","listen","unix"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}