ginuerzh/gost · error

ports list must look like 80,8000-9000, given: %s

Error message

ports list must look like 80,8000-9000, given: %s

What it means

ParsePermissions validates each permission entry of the form [actions]:[hosts]:[ports]. The ports segment is parsed by ParsePortSet, which only accepts comma-separated single ports or ranges like 80,8000-9000. When that parse fails, the parser wraps it in this error and returns no Permissions.

Source

Thrown at permissions.go:165

		switch len(parts) {
		case 3:
			actions, err := ParseStringSet(parts[0])

			if err != nil {
				return nil, fmt.Errorf("action list must look like connect,bind given: %s", parts[0])
			}

			hosts, err := ParseStringSet(parts[1])

			if err != nil {
				return nil, fmt.Errorf("hosts list must look like google.pl,*.google.com given: %s", parts[1])
			}

			ports, err := ParsePortSet(parts[2])

			if err != nil {
				return nil, fmt.Errorf("ports list must look like 80,8000-9000, given: %s", parts[2])
			}

			permission := Permission{Actions: *actions, Hosts: *hosts, Ports: *ports}

			*ps = append(*ps, permission)
		default:
			return nil, fmt.Errorf("permission must have format [actions]:[hosts]:[ports] given: %s", perm)
		}
	}

	return ps, nil
}

// Can tests whether the given action and host:port is allowed by this Permissions.
func (ps *Permissions) Can(action string, host string, port int) bool {
	for _, p := range *ps {
		if p.Actions.Contains(action) && p.Hosts.Contains(host) && p.Ports.Contains(port) {
			return true

View on GitHub (pinned to a33fdbf4c9)

Solutions

  1. Check the third segment (parts[2]) at permissions.go:165 — it must contain only numbers, commas, and a-b ranges like 80,8000-9000
  2. Replace service names with numeric ports: "https" -> "443"
  3. Fix invalid ranges (start <= end, values 0-65535): "9000-8000" -> "8000-9000"
  4. Pre-validate each port token with strconv.Atoi and range checks before calling ParsePermissions

Example fix

// before
perms, err := gost.ParsePermissions("connect:*.example.com:https,9000-8000")
// after
perms, err := gost.ParsePermissions("connect:*.example.com:443,8000-9000")
Defensive patterns

Strategy: validation

Validate before calling

func validPortSet(s string) bool {
    for _, tok := range strings.Split(s, ",") {
        if tok == "" { continue }
        if i := strings.IndexByte(tok, '-'); i >= 0 {
            lo, e1 := strconv.Atoi(tok[:i]); hi, e2 := strconv.Atoi(tok[i+1:])
            if e1 != nil || e2 != nil || lo > hi || lo < 0 || hi > 65535 { return false }
            continue
        }
        p, err := strconv.Atoi(tok)
        if err != nil || p < 0 || p > 65535 { return false }
    }
    return true
}

Type guard

func isNumericPortToken(s string) bool {
    p, err := strconv.Atoi(s)
    return err == nil && p >= 0 && p <= 65535
}

Try / catch

perms, err := gost.ParsePermissions(input)
if err != nil {
    if strings.Contains(err.Error(), "ports list must look like") {
        log.Fatalf("invalid ports segment in %q: %v", input, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling ParsePermissions with a permission whose third colon-separated field contains non-numeric tokens, invalid ranges (e.g. 9000-8000, 70000), or text like "http" — e.g. "connect:google.pl:http" or "bind:*.example.com:80,tcp".

Common situations: Typos in port specs in gost configs, service names ("https") instead of numbers, reversed ranges, ports above 65535, or a unicode en-dash instead of ASCII '-' from copy-paste.

Related errors


AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02). Data as JSON: /api/errors/00e39fefa503a290. Report an issue: GitHub.