txthinking/brook · error

--cert must be with absolute path

Error message

--cert must be with absolute path

What it means

When --cert is provided to the brook server subcommand it must be an absolute path, because the TLS certificate file may be re-read by the running process and relative paths are cwd-dependent. If the flag is non-empty and filepath.IsAbs() returns false, validation returns this error immediately.

Source

Thrown at cli/brook/main.go:862

			Action: func(c *cli.Context) error {
				if c.Bool("example") {
					fmt.Println("brook wssserver --domainaddress domain.com:9999 --password hello")
					return nil
				}
				if c.String("domainaddress") == "" || c.String("password") == "" {
					return cli.ShowSubcommandHelp(c)
				}
				if c.String("blockDomainList") != "" && !strings.HasPrefix(c.String("blockDomainList"), "http://") && !strings.HasPrefix(c.String("blockDomainList"), "https://") && !filepath.IsAbs(c.String("blockDomainList")) {
					return errors.New("--blockDomainList must be with absolute path")
				}
				if c.String("blockCIDR4List") != "" && !strings.HasPrefix(c.String("blockCIDR4List"), "http://") && !strings.HasPrefix(c.String("blockCIDR4List"), "https://") && !filepath.IsAbs(c.String("blockCIDR4List")) {
					return errors.New("--blockCIDR4List must be with absolute path")
				}
				if c.String("blockCIDR6List") != "" && !strings.HasPrefix(c.String("blockCIDR6List"), "http://") && !strings.HasPrefix(c.String("blockCIDR6List"), "https://") && !filepath.IsAbs(c.String("blockCIDR6List")) {
					return errors.New("--blockCIDR6List must be with absolute path")
				}
				if c.String("cert") != "" && !filepath.IsAbs(c.String("cert")) {
					return errors.New("--cert must be with absolute path")
				}
				if c.String("certkey") != "" && !filepath.IsAbs(c.String("certkey")) {
					return errors.New("--certkey must be with absolute path")
				}
				if c.String("blockDomainList") != "" || c.String("blockCIDR4List") != "" || c.String("blockCIDR6List") != "" || len(c.StringSlice("blockGeoIP")) != 0 {
					p, err := block.NewBlock(c.String("blockDomainList"), c.String("blockCIDR4List"), c.String("blockCIDR6List"), c.StringSlice("blockGeoIP"), c.Int("updateListInterval"))
					if err != nil {
						return err
					}
					p.TouchBrook()
					if c.Int("updateListInterval") != 0 {
						g.Add(&runnergroup.Runner{
							Start: func() error {
								p.Update()
								return nil
							},
							Stop: func() error {
								p.Stop()

View on GitHub (pinned to 5cd13ef3b1)

Solutions

  1. Pass an absolute path: --cert /etc/brook/server.crt
  2. Generate/locate with absolute paths: --cert "$(realpath server.crt)"
  3. Ensure --certkey is also absolute, since it has the same requirement

Example fix

// before
brook server --cert server.crt --certkey server.key
// after
brook server --cert /etc/brook/server.crt --certkey /etc/brook/server.key
Defensive patterns

Strategy: validation

Validate before calling

if cert := flagValue; cert != "" && !filepath.IsAbs(cert) {
    return fmt.Errorf("--cert must be an absolute path, got %q", cert)
}

Type guard

func isAbsPath(p string) bool { return filepath.IsAbs(p) }

Prevention

When it happens

Trigger: Running `brook server` with --cert set to a relative path, e.g. --cert ./server.crt or --cert server.crt, together with --certkey.

Common situations: Setting up TLS for the server with certificate files in the launch directory; works when testing manually from that directory's parent assumptions but fails because brook demands absolute paths by design.

Understand the failure class

Background: "unknown output mode", "invalid value for flag", "expects true/false": fixing invalid flag value errors in CLI tools — this error's family across 24 libraries.

Related errors


AI-assisted analysis of txthinking/brook@5cd13ef3b1 (2026-09-06). Data as JSON: /api/errors/a8eb911a2b601c57. Report an issue: GitHub.