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 trueView on GitHub (pinned to a33fdbf4c9)
Solutions
- Check the third segment (parts[2]) at permissions.go:165 — it must contain only numbers, commas, and a-b ranges like 80,8000-9000
- Replace service names with numeric ports: "https" -> "443"
- Fix invalid ranges (start <= end, values 0-65535): "9000-8000" -> "8000-9000"
- 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
- Use only digits, commas, and '-' in the ports segment; no service names like "https"
- Ensure ranges go low-high and stay within 0-65535
- Copy config values from a plain-text editor to avoid en-dash/unicode lookalikes of '-'
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
- hosts list must look like google.pl,*.google.com given: %s
- permission must have format [actions]:[hosts]:[ports] given:
- ErrInvalidNode
- must specify at least one port
- cannot be empty
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/00e39fefa503a290.
Report an issue: GitHub.