{"record":{"id":"00e39fefa503a290","repo":"ginuerzh/gost","slug":"ports-list-must-look-like-80-8000-9000-given-s","errorCode":null,"errorMessage":"ports list must look like 80,8000-9000, given: %s","messagePattern":"ports list must look like 80,8000-9000, given: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"permissions.go","lineNumber":165,"sourceCode":"\n\t\tswitch len(parts) {\n\t\tcase 3:\n\t\t\tactions, err := ParseStringSet(parts[0])\n\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"action list must look like connect,bind given: %s\", parts[0])\n\t\t\t}\n\n\t\t\thosts, err := ParseStringSet(parts[1])\n\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"hosts list must look like google.pl,*.google.com given: %s\", parts[1])\n\t\t\t}\n\n\t\t\tports, err := ParsePortSet(parts[2])\n\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"ports list must look like 80,8000-9000, given: %s\", parts[2])\n\t\t\t}\n\n\t\t\tpermission := Permission{Actions: *actions, Hosts: *hosts, Ports: *ports}\n\n\t\t\t*ps = append(*ps, permission)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"permission must have format [actions]:[hosts]:[ports] given: %s\", perm)\n\t\t}\n\t}\n\n\treturn ps, nil\n}\n\n// Can tests whether the given action and host:port is allowed by this Permissions.\nfunc (ps *Permissions) Can(action string, host string, port int) bool {\n\tfor _, p := range *ps {\n\t\tif p.Actions.Contains(action) && p.Hosts.Contains(host) && p.Ports.Contains(port) {\n\t\t\treturn true","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/ginuerzh/gost/blob/a33fdbf4c98034f4bfeeaea9868909822b9c526d/permissions.go#L147-L183","documentation":"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.","triggerScenarios":"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\".","commonSituations":"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.","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"],"exampleFix":"// before\nperms, err := gost.ParsePermissions(\"connect:*.example.com:https,9000-8000\")\n// after\nperms, err := gost.ParsePermissions(\"connect:*.example.com:443,8000-9000\")","handlingStrategy":"validation","validationCode":"func validPortSet(s string) bool {\n    for _, tok := range strings.Split(s, \",\") {\n        if tok == \"\" { continue }\n        if i := strings.IndexByte(tok, '-'); i >= 0 {\n            lo, e1 := strconv.Atoi(tok[:i]); hi, e2 := strconv.Atoi(tok[i+1:])\n            if e1 != nil || e2 != nil || lo > hi || lo < 0 || hi > 65535 { return false }\n            continue\n        }\n        p, err := strconv.Atoi(tok)\n        if err != nil || p < 0 || p > 65535 { return false }\n    }\n    return true\n}","typeGuard":"func isNumericPortToken(s string) bool {\n    p, err := strconv.Atoi(s)\n    return err == nil && p >= 0 && p <= 65535\n}","tryCatchPattern":"perms, err := gost.ParsePermissions(input)\nif err != nil {\n    if strings.Contains(err.Error(), \"ports list must look like\") {\n        log.Fatalf(\"invalid ports segment in %q: %v\", input, err)\n    }\n    return err\n}","preventionTips":["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 '-'"],"tags":["config","parsing","ports","gost"],"backgroundTag":"config-parse-error","analyzedSha":"a33fdbf4c98034f4bfeeaea9868909822b9c526d","analyzedAt":"2026-09-02T22:15:54.506Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}