{"record":{"id":"1d75deb09a9db364","repo":"fatedier/frp","slug":"unknown-proxy-type-s-1d75de","errorCode":null,"errorMessage":"unknown proxy type: %s","messagePattern":"unknown proxy type: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/v1/decode.go","lineNumber":56,"sourceCode":"\ntype typedEnvelope struct {\n\tType   string           `json:\"type\"`\n\tPlugin jsonx.RawMessage `json:\"plugin,omitempty\"`\n}\n\nfunc DecodeProxyConfigurerJSON(b []byte, options DecodeOptions) (ProxyConfigurer, error) {\n\tif isJSONNull(b) {\n\t\treturn nil, errors.New(\"type is required\")\n\t}\n\n\tvar env typedEnvelope\n\tif err := jsonx.Unmarshal(b, &env); err != nil {\n\t\treturn nil, err\n\t}\n\n\tconfigurer := NewProxyConfigurerByType(ProxyType(env.Type))\n\tif configurer == nil {\n\t\treturn nil, fmt.Errorf(\"unknown proxy type: %s\", env.Type)\n\t}\n\tif err := decodeJSONWithOptions(b, configurer, options); err != nil {\n\t\treturn nil, fmt.Errorf(\"unmarshal ProxyConfig error: %v\", err)\n\t}\n\n\tif len(env.Plugin) > 0 && !isJSONNull(env.Plugin) {\n\t\tplugin, err := DecodeClientPluginOptionsJSON(env.Plugin, options)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unmarshal proxy plugin error: %v\", err)\n\t\t}\n\t\tconfigurer.GetBaseConfig().Plugin = plugin\n\t}\n\treturn configurer, nil\n}\n\nfunc DecodeVisitorConfigurerJSON(b []byte, options DecodeOptions) (VisitorConfigurer, error) {\n\tif isJSONNull(b) {\n\t\treturn nil, errors.New(\"type is required\")","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/config/v1/decode.go#L38-L74","documentation":"DecodeProxyConfigurerJSON in pkg/config/v1/decode.go dispatches on the JSON envelope's \"type\" field to construct the right ProxyConfigurer via NewProxyConfigurerByType. If the type string does not match any registered proxy type (tcp, udp, xtcp, stcp, sudp, tcpmux, http, https, plugin variants), the factory returns nil and this error names the offending type. It fires before any field-level decoding of the proxy object.","triggerScenarios":"Calling DecodeProxyConfigurerJSON (directly, or via DecodeClientConfigJSON over a proxies[] entry) with a proxy whose \"type\" is misspelled or unregistered, e.g. \"Tcp\" (case-sensitive), \"web\", \"grpc\", or a plugin name placed in \"type\" instead of \"plugin.type\". Also when the JSON lacks quotes/has a broken type field value that still unmarshals.","commonSituations":"Upgrading from frp versions whose accepted type sets differ; using a third-party proxy type from a plugin ecosystem not compiled into this build; case mismatches ('TCP' vs 'tcp'); putting the plugin name into proxy \"type\" (e.g. type=\"static_file\" instead of type=\"tcp\" + plugin settings).","solutions":["Set \"type\" to a supported built-in value: tcp, udp, xtcp, stcp, sudp, tcpmux, http, or https.","Check case and whitespace — the match is exact and lowercase.","For plugin-based proxies, keep type as the transport (e.g. \"tcp\") and put the plugin name under plugin.type, not in the proxy type field."],"exampleFix":"// before\n{ \"type\": \"Tcp\", \"localPort\": 80 }\n\n// after\n{ \"type\": \"tcp\", \"localPort\": 80 }","handlingStrategy":"validation","validationCode":"// Check the proxy type against known types before decoding.\nvar knownProxyTypes = map[string]bool{\n\t\"tcp\": true, \"udp\": true, \"xtcp\": true, \"stcp\": true,\n\t\"sudp\": true, \"tcpmux\": true, \"http\": true, \"https\": true,\n}\nfunc validProxyType(t string) error {\n\tif !knownProxyTypes[t] {\n\t\treturn fmt.Errorf(\"unknown proxy type %q; want one of tcp,udp,xtcp,stcp,sudp,tcpmux,http,https\", t)\n\t}\n\treturn nil\n}","typeGuard":"func isKnownProxyType(t string) bool { return knownProxyTypes[t] }","tryCatchPattern":"if cfg, err := v1.DecodeProxyConfigurerJSON(b, opts); err != nil {\n\tif strings.Contains(err.Error(), \"unknown proxy type\") {\n\t\t// surface the type string and list supported types to the operator\n\t}\n\treturn err\n}","preventionTips":["Keep proxy types lowercase and exactly spelled.","Pin your config schema to your frp version's supported types.","Put plugin names in plugin.type, never in proxy type."],"tags":["go","frp","config","json","proxy","decode"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}