caddyserver/caddy · error

unable to set permissions (%s) on %s: %v

Error message

unable to set permissions (%s) on %s: %v

What it means

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.

Source

Thrown at listeners.go:199

			lnKey := listenerKey(na.Network, address)
			ln, err = listenReusable(ctx, lnKey, na.Network, address, config)
		}
	}

	if err != nil {
		return nil, err
	}

	if ln == nil {
		return nil, fmt.Errorf("unsupported network type: %s", na.Network)
	}

	if IsUnixNetwork(na.Network) {
		isAbstractUnixSocket := strings.HasPrefix(address, "@")
		if !isAbstractUnixSocket {
			err = os.Chmod(address, unixFileMode)
			if err != nil {
				return nil, fmt.Errorf("unable to set permissions (%s) on %s: %v", unixFileMode, address, err)
			}
		}
	}

	return ln, nil
}

// IsUnixNetwork returns true if na.Network is
// unix, unixgram, or unixpacket.
func (na NetworkAddress) IsUnixNetwork() bool {
	return IsUnixNetwork(na.Network)
}

// IsFdNetwork returns true if na.Network is
// fd or fdgram.
func (na NetworkAddress) IsFdNetwork() bool {
	return IsFdNetwork(na.Network)
}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Ensure the Caddy process user owns or can chmod the socket path (systemd RuntimeDirectory=/run/caddy).
  2. Remove stale socket files before start or enable Caddy's unix socket reuse.
  3. Move the socket to a directory the service fully controls.

Example fix

# before: /run owned by root, caddy runs as caddy
listen unix/run/caddy.sock
# after (systemd unit)
[Service]
RuntimeDirectory=caddy
listen unix/run/caddy/caddy.sock
Defensive patterns

Strategy: validation

Validate before calling

func canChmod(path string) bool {
    info, err := os.Stat(path)
    return err == nil && info.Mode().IsRegular() == false || err == nil
}

Prevention

When it happens

Trigger: 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).

Common situations: Running Caddy as non-root writing into /run without RuntimeDirectory; a second process deleting the socket concurrently; unusual container volumes mounted with restricted options.

Related errors


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