fatedier/frp · error
unmarshal proxy plugin error: %v
Error message
unmarshal proxy plugin error: %v
What it means
After a proxy's own fields decode successfully, DecodeProxyConfigurerJSON decodes the embedded "plugin" object with DecodeClientPluginOptionsJSON. If that plugin object has a "type" that is not in clientPluginOptionsTypeMap (unknown plugin), or its fields fail decoding, the error is wrapped as 'unmarshal proxy plugin error'. The proxy is otherwise valid; only its plugin stanza is broken.
Source
Thrown at pkg/config/v1/decode.go:65
}
var env typedEnvelope
if err := jsonx.Unmarshal(b, &env); err != nil {
return nil, err
}
configurer := NewProxyConfigurerByType(ProxyType(env.Type))
if configurer == nil {
return nil, fmt.Errorf("unknown proxy type: %s", env.Type)
}
if err := decodeJSONWithOptions(b, configurer, options); err != nil {
return nil, fmt.Errorf("unmarshal ProxyConfig error: %v", err)
}
if len(env.Plugin) > 0 && !isJSONNull(env.Plugin) {
plugin, err := DecodeClientPluginOptionsJSON(env.Plugin, options)
if err != nil {
return nil, fmt.Errorf("unmarshal proxy plugin error: %v", err)
}
configurer.GetBaseConfig().Plugin = plugin
}
return configurer, nil
}
func DecodeVisitorConfigurerJSON(b []byte, options DecodeOptions) (VisitorConfigurer, error) {
if isJSONNull(b) {
return nil, errors.New("type is required")
}
var env typedEnvelope
if err := jsonx.Unmarshal(b, &env); err != nil {
return nil, err
}
configurer := NewVisitorConfigurerByType(VisitorType(env.Type))
if configurer == nil {View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Set plugin.type to a supported plugin name exactly as documented (e.g. static_file, http2https, unix_domain_socket, socks5, https2http...).
- Fix the wrapped error's named plugin field (wrong type or renamed option).
- Upgrade frp if the plugin exists only in a newer release, or drop the plugin block.
Example fix
// before
{ "type": "tcp", "plugin": { "type": "staticfile", "localPath": "/srv" } }
// after
{ "type": "tcp", "plugin": { "type": "static_file", "localPath": "/srv" } } Defensive patterns
Strategy: validation
Validate before calling
// Verify the proxy's plugin block type is registered before decoding the client config.
func validClientPluginType(pluginJSON []byte) error {
var env struct{ Type string `json:"type"` }
if err := json.Unmarshal(pluginJSON, &env); err != nil {
return err
}
switch env.Type {
case "static_file", "http2https", "https2http", "unix_domain_socket", "socks5", "proxy_protocol":
return nil
}
return fmt.Errorf("plugin type %q not supported by this frp build", env.Type)
} Type guard
func isKnownClientPlugin(t string) bool {
switch t {
case "static_file", "http2https", "https2http", "unix_domain_socket", "socks5", "proxy_protocol":
return true
}
return false
} Try / catch
if _, err := v1.DecodeClientConfigJSON(b, opts); err != nil {
if strings.Contains(err.Error(), "unmarshal proxy plugin error") {
// inspect plugin.type and plugin fields of the indexed proxy
}
return err
} Prevention
- Use exact snake_case plugin names from the docs.
- Match plugin names to your frp version; upgrade both frpc and frps together.
- Keep plugin options under plugin.* keys with current field names.
When it happens
Trigger: A proxy with a plugin block whose type is misspelled or unsupported in this build (e.g. plugin.type="staticfile" instead of "static_file", or a plugin not compiled in), or plugin option fields of the wrong type. Triggered via DecodeClientConfigJSON or direct DecodeProxyConfigurerJSON on such a proxy.
Common situations: Plugin name typos (static_file vs staticfile); using a plugin introduced in a newer frp version against an older binary; plugin options renamed between versions (e.g. plugin-local-path vs localPath after the TOML migration).
Related errors
- unmarshal visitor plugin error: %v
- unknown plugin type: %s
- unmarshal ClientPluginOptions error: %v
- unknown visitor plugin type: %s
- unmarshal VisitorPluginOptions error: %v
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/05d118d3ec1f0423.
Report an issue: GitHub.