fatedier/frp · error
invalid protocol
Error message
invalid protocol
What it means
ClientCommonConf.Validate in the legacy INI client config rejects any protocol value outside the allowlist tcp, kcp, quic, websocket, wss. The protocol field selects the transport frpc uses to connect to frps, so unknown values cannot be mapped to a dialer.
Source
Thrown at pkg/config/legacy/client.go:384
}
}
if !cfg.TLSEnable {
if cfg.TLSCertFile != "" {
fmt.Println("WARNING! tls_cert_file is invalid when tls_enable is false")
}
if cfg.TLSKeyFile != "" {
fmt.Println("WARNING! tls_key_file is invalid when tls_enable is false")
}
if cfg.TLSTrustedCaFile != "" {
fmt.Println("WARNING! tls_trusted_ca_file is invalid when tls_enable is false")
}
}
if !slices.Contains([]string{"tcp", "kcp", "quic", "websocket", "wss"}, cfg.Protocol) {
return fmt.Errorf("invalid protocol")
}
for _, f := range cfg.IncludeConfigFiles {
absDir, err := filepath.Abs(filepath.Dir(f))
if err != nil {
return fmt.Errorf("include: parse directory of %s failed: %v", f, err)
}
if _, err := os.Stat(absDir); os.IsNotExist(err) {
return fmt.Errorf("include: directory of %s not exist", f)
}
}
return nil
}
View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Change protocol to one of: tcp, kcp, quic websocket, wss (exactly lowercase)
- Check for typos and surrounding quotes/whitespace in the INI value
- Verify the matching server side has the transport enabled (e.g. quic/websocket ports on frps) after fixing the value
Example fix
# before [common] protocol = http # after [common] protocol = websocket
Defensive patterns
Strategy: validation
Validate before calling
var allowedProtocols = map[string]bool{"tcp":true,"kcp":true,"quic":true,"websocket":true,"wss":true}
if !allowedProtocols[common.Protocol] {
return fmt.Errorf("protocol %q not supported; use tcp/kcp/quic/websocket/wss", common.Protocol)
} Type guard
func isSupportedProtocol(p string) bool {
switch p {
case "tcp", "kcp", "quic", "websocket", "wss":
return true
}
return false
} Try / catch
if err := cfg.Validate(); err != nil { if strings.HasPrefix(err.Error(), "invalid protocol") { /* surface allowlist to the user */ } return err } Prevention
- Keep the protocol allowlist next to your config templates
- Lint INI values for lowercase exact matches
- Document supported transports per frp version in your runbook
When it happens
Trigger: A legacy frpc.ini with protocol = http, protocol = grpc, a typo like protocal/websockt, or trailing whitespace/case differences (the check is case-sensitive, only lowercase matches pass).
Common situations: Copy-paste from nginx/other proxy docs where 'http' is a valid protocol; upgrading frp and assuming newly discussed transports exist in the installed version; kcp/quic builds where the string was misspelled.
Related errors
- invalid heartbeat_timeout, heartbeat_timeout is less than he
- parse config error: %v
- invalid type [%s]
- type shouldn't be empty
- type [%s] error
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/e08d6160be44ad59.
Report an issue: GitHub.