fatedier/frp · error

plugin [%s] is not registered

Error message

plugin [%s] is not registered

What it means

Client-side plugin factory lookup failed: Create() was asked for a plugin name that has no registered CreatorFn in the client plugin registry. The registry is populated by init() functions of built-in plugins (http, https2http, socks5, static_file, unix_domain_socket, ...), so an unknown name means either a typo or a plugin type only available in a different build.

Source

Thrown at pkg/plugin/client/plugin.go:52

}

// Creators is used for create plugins to handle connections.
var creators = make(map[string]CreatorFn)

type CreatorFn func(pluginCtx PluginContext, options v1.ClientPluginOptions) (Plugin, error)

func Register(name string, fn CreatorFn) {
	if _, exist := creators[name]; exist {
		panic(fmt.Sprintf("plugin [%s] is already registered", name))
	}
	creators[name] = fn
}

func Create(pluginName string, pluginCtx PluginContext, options v1.ClientPluginOptions) (p Plugin, err error) {
	if fn, ok := creators[pluginName]; ok {
		p, err = fn(pluginCtx, options)
	} else {
		err = fmt.Errorf("plugin [%s] is not registered", pluginName)
	}
	return
}

type ConnectionInfo struct {
	Conn           io.ReadWriteCloser
	UnderlyingConn net.Conn

	ProxyProtocolHeader *pp.Header
	SrcAddr             net.Addr
	DstAddr             net.Addr
}

type Plugin interface {
	Name() string

	Handle(ctx context.Context, connInfo *ConnectionInfo)
	Close() error

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Check the plugin type string against the supported list in the frp docs for your version
  2. Upgrade frpc to the version that ships the plugin you want
  3. If it is a custom plugin, register it with plugin/client.Register before Create is called

Example fix

// before
[proxies.plugin]
type = "https2htp"  // typo
localAddr = "127.0.0.1:80"

// after
type = "https2http"
localAddr = "127.0.0.1:80"
Defensive patterns

Strategy: validation

Validate before calling

// Reject config before starting the proxy
if !plugin.ValidTypes()[cfg.Plugin.Type] {
    return fmt.Errorf("unknown client plugin type %q; valid: %v", cfg.Plugin.Type, plugin.ValidTypes())
}

Try / catch

if _, err := plugin.Create(name, pCtx, opts); err != nil {
    if strings.Contains(err.Error(), "is not registered") {
        return fmt.Errorf("config error: %w — check plugin type spelling and frpc version", err)
    }
    return err
}

Prevention

When it happens

Trigger: A proxy config whose [proxies.plugin].type is not one of the registered client plugin names — misspelled type string, or a server-side-only plugin name used on the client.

Common situations: type = "https2htp" typo; using a plugin introduced in a newer frp version while running an older frpc; custom plugin compiled out of the build; confusing server plugins (op-style) with client proxy plugins.

Related errors


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