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

  1. Change protocol to one of: tcp, kcp, quic websocket, wss (exactly lowercase)
  2. Check for typos and surrounding quotes/whitespace in the INI value
  3. 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

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


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