ginuerzh/gost · error

action list must look like connect,bind given: %s

Error message

action list must look like connect,bind given: %s

What it means

ParsePermissions expects each permission rule to have three dash-separated parts: actions, hosts, and ports. When the first part fails ParseStringSet (empty or malformed action list), the parser returns this error telling you the actions field must look like a comma-separated list such as connect,bind.

Source

Thrown at permissions.go:153

// ParsePermissions parses the s to a Permissions.
func ParsePermissions(s string) (*Permissions, error) {
	ps := &Permissions{}

	if s == "" {
		return &Permissions{}, nil
	}

	perms := strings.Split(s, " ")

	for _, perm := range perms {
		parts := strings.Split(perm, ":")

		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:

View on GitHub (pinned to a33fdbf4c9)

Solutions

  1. Format each rule as actions-hosts-ports, e.g. "connect,bind *.example.com 443".
  2. Ensure the actions field is a non-empty comma-separated list of known actions (connect, bind).
  3. Check for stray/leading dashes or smart quotes introduced by editors; rewrite the rule in plain ASCII.
  4. Pre-validate with ParseStringSet(parts[0]) in tests before shipping configs.

Example fix

// before
permissions = "-*.google.com 80,443"
// after
permissions = "connect,bind *.google.com 80,443"
Defensive patterns

Strategy: validation

Validate before calling

parts := strings.Split(rule, "-")
if len(parts) != 3 {
    return fmt.Errorf("rule must be actions-hosts-ports, got %q", rule)
}
if _, err := ParseStringSet(parts[0]); err != nil {
    return fmt.Errorf("invalid action list %q", parts[0])
}

Try / catch

perms, err := ParsePermissions(rules)
if err != nil {
    return fmt.Errorf("bad permissions %q: %w", rules, err)
}

Prevention

When it happens

Trigger: Calling ParsePermissions with a rule like "connect * *" where parts[0] is empty (leading dash, e.g. "-host:80"), contains invalid characters for the string-set parser, or the whole rule is malformed so parts[0] is not a valid action list.

Common situations: Malformed permission strings in gost config (missing action field, wrong separator, extra/missing dashes); hand-edited permission lines; whitespace or unicode dashes instead of ASCII '-'.

Related errors


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