caddyserver/caddy · error

invalid file descriptor: %v

Error message

invalid file descriptor: %v

What it means

When the listen network is 'fd' or 'fdgram', Caddy interprets the address as an integer file descriptor number passed to the process (socket activation). This error means the address could not be parsed as an unsigned integer of the platform's int size (ParseUint with base 0, so decimal/hex/octal literals are accepted, but non-numeric strings are not).

Source

Thrown at listen.go:40

	"net"
	"os"
	"slices"
	"strconv"
	"sync"
	"sync/atomic"
	"time"

	"go.uber.org/zap"
)

func listenReusable(ctx context.Context, lnKey string, network, address string, config net.ListenConfig) (any, error) {
	var socketFile *os.File

	fd := slices.Contains([]string{"fd", "fdgram"}, network)
	if fd {
		socketFd, err := strconv.ParseUint(address, 0, strconv.IntSize)
		if err != nil {
			return nil, fmt.Errorf("invalid file descriptor: %v", err)
		}

		func() {
			socketFilesMu.Lock()
			defer socketFilesMu.Unlock()

			socketFdWide := uintptr(socketFd)
			var ok bool

			socketFile, ok = socketFiles[socketFdWide]

			if !ok {
				socketFile = os.NewFile(socketFdWide, lnKey)
				if socketFile != nil {
					socketFiles[socketFdWide] = socketFile
				}
			}
		}()

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Set the address to the bare descriptor number, e.g. network 'fd', address '3'.
  2. Base-0 prefixes are allowed: '0x3' works if you prefer hex.
  3. If you meant a unix path or TCP address, use network 'unix' or 'tcp' instead of 'fd'.
  4. Verify the descriptor is actually passed to the process (systemd sockets, exec inheritance) — but this error is purely about numeric parsing.

Example fix

// before
{
  listen fd:3
}
// after
{
  listen fd 3
}
Defensive patterns

Strategy: validation

Validate before calling

func validFdAddress(addr string) bool {
    _, err := strconv.ParseUint(addr, 0, strconv.IntSize)
    return err == nil
}

Prevention

When it happens

Trigger: Configuring listen network 'fd' with a non-numeric address such as 'fd:3', 'socket', '3rd', an empty string, or a value larger than the max int on the platform.

Common situations: Migrating a config from systemd socket activation where the address was written as a label or with a colon prefix; typos; or templates that leave the fd placeholder empty.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/9016c2527662308f. Report an issue: GitHub.