fatedier/frp · error

type shouldn't be empty

Error message

type shouldn't be empty

What it means

NewVisitorConfFromIni reads the type key of a visitor INI section; unlike proxies, visitors have no default. If type is empty the config is rejected immediately with 'type shouldn't be empty'. Visitors must explicitly declare stcp, sudp, or xtcp.

Source

Thrown at pkg/config/legacy/visitor.go:173

	if cfg.MaxRetriesAnHour <= 0 {
		cfg.MaxRetriesAnHour = 8
	}
	if cfg.MinRetryInterval <= 0 {
		cfg.MinRetryInterval = 90
	}
	if cfg.FallbackTimeoutMs <= 0 {
		cfg.FallbackTimeoutMs = 1000
	}
	return
}

// Visitor loaded from ini
func NewVisitorConfFromIni(prefix string, name string, section *ini.Section) (VisitorConf, error) {
	// section.Key: if key not exists, section will set it with default value.
	visitorType := VisitorType(section.Key("type").String())

	if visitorType == "" {
		return nil, fmt.Errorf("type shouldn't be empty")
	}

	conf := DefaultVisitorConf(visitorType)
	if conf == nil {
		return nil, fmt.Errorf("type [%s] error", visitorType)
	}

	if err := conf.UnmarshalFromIni(prefix, name, section); err != nil {
		return nil, fmt.Errorf("type [%s] error", visitorType)
	}
	return conf, nil
}

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Add type = stcp (or sudp/xtcp) to the visitor section
  2. If the section was not meant to be a visitor, rename it so it is not detected as one (check the naming convention used to detect visitor sections)
  3. Validate with frpc verify -c frpc.ini

Example fix

# before
[secret-visitor]
name = sv
server_name = secret

# after
[secret-visitor]
type = stcp
name = sv
server_name = secret
Defensive patterns

Strategy: validation

Validate before calling

if section.Key("type").String() == "" {
    return fmt.Errorf("visitor section [%s] missing type (stcp/sudp/xtcp)", section.Name())
}

Type guard

func hasVisitorType(s *ini.Section) bool { return s.Key("type").String() != "" }

Try / catch

if _, err := legacy.NewVisitorConfFromIni(prefix, name, section); err != nil && err.Error() == "type shouldn't be empty" { /* add type key */ }

Prevention

When it happens

Trigger: A [visitor.x] or similarly named section in legacy frpc.ini where the type key is missing or blank. Merely having a section named like a visitor without a type triggers it during LoadAllProxyConfsFromIni.

Common situations: Users adding a visitor section by copying a proxy section and deleting fields; forgetting that visitors require type while proxies silently default to tcp.

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/f0f675cd12cabb3b. Report an issue: GitHub.