fatedier/frp · error

invalid type [%s]

Error message

invalid type [%s]

What it means

When building a proxy config from a legacy INI section, frp reads the type key (defaulting to tcp when absent) and asks DefaultProxyConf for a struct for that type. If the type string does not map to a known proxy kind (tcp, udp, xtcp, stcp, sudp, http, https, tcpmux), DefaultProxyConf returns nil and this 'invalid type [<type>]' error is returned.

Source

Thrown at pkg/config/legacy/proxy.go:87

// Proxy Conf Loader
// DefaultProxyConf creates a empty ProxyConf object by proxyType.
// If proxyType doesn't exist, return nil.
func DefaultProxyConf(proxyType ProxyType) ProxyConf {
	return NewConfByType(proxyType)
}

// Proxy loaded from ini
func NewProxyConfFromIni(prefix, name string, section *ini.Section) (ProxyConf, error) {
	// section.Key: if key not exists, section will set it with default value.
	proxyType := ProxyType(section.Key("type").String())
	if proxyType == "" {
		proxyType = ProxyTypeTCP
	}

	conf := DefaultProxyConf(proxyType)
	if conf == nil {
		return nil, fmt.Errorf("invalid type [%s]", proxyType)
	}

	if err := conf.UnmarshalFromIni(prefix, name, section); err != nil {
		return nil, err
	}
	return conf, nil
}

// LocalSvrConf configures what location the client will to, or what
// plugin will be used.
type LocalSvrConf struct {
	// LocalIP specifies the IP address or host name to to.
	LocalIP string `ini:"local_ip" json:"local_ip"`
	// LocalPort specifies the port to to.
	LocalPort int `ini:"local_port" json:"local_port"`

	// Plugin specifies what plugin should be used for ng. If this value
	// is set, the LocalIp and LocalPort values will be ignored. By default,

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Set type to a supported value: tcp, udp, xtcp, stcp, sudp, http, https, or tcpmux
  2. Check spelling/case (type values are lowercase)
  3. Confirm the type exists in your frpc version's docs

Example fix

# before
[my-proxy]
type = tlcp

# after
[my-proxy]
type = stcp
Defensive patterns

Strategy: type-guard

Validate before calling

validTypes := map[string]bool{"tcp":true,"udp":true,"xtcp":true,"stcp":true,"sudp":true,"http":true,"https":true,"tcpmux":true}
if t := section.Key("type").String(); t != "" && !validTypes[t] {
    return fmt.Errorf("unsupported proxy type %q", t)
}

Type guard

func isValidProxyType(t string) bool {
    switch t {
    case "tcp", "udp", "xtcp", "stcp", "sudp", "http", "https", "tcpmux":
        return true
    }
    return false
}

Try / catch

if _, err := legacy.NewProxyConfFromIni(prefix, name, section); err != nil && strings.HasPrefix(err.Error(), "invalid type") { /* report supported list, fix section */ }

Prevention

When it happens

Trigger: A proxy section like [my-web] with type = http2, type = tcpmuxhttp, or any unsupported/misspelled value. Note the empty string does NOT trigger it — empty defaults to tcp; only non-empty unknown values do.

Common situations: Typos in type values; using a type supported by a newer frp version against an older frpc; assuming plugin-based sections still need exotic type values.

Related errors


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