hyperledger/fabric · critical
plugin with name wasn't found
Error message
plugin with name %s wasn't found
What it means
PluginValidator.getOrCreatePlugin looks up a validation-plugin factory by the name stored in the chaincode definition (ctx.PluginName); no factory with that name is registered. Fabric throws this when the peer was not configured with the named validation plugin, so transactions for that chaincode cannot be validated.
Solutions
- Register the plugin in the peer's core.yaml under validators.<pluginName> (library path + command) and restart the peer.
- Correct the plugin name in the chaincode definition to one registered on all validating peers (use 'vscc' for default validation).
- Deploy the plugin shared library/bytes to every validating peer in the channel.
- Ensure all peers run the same build/config so definitions referencing custom plugins resolve everywhere.
Example fix
// before (core.yaml)
validators: {}
// after
validators:
myvscc:
library: /etc/hyperledger/fabric/plugins/myvscc.so Defensive patterns
Strategy: validation
Validate before calling
// before approving a definition with a custom plugin, check peer config
const cfg = yaml.load(fs.readFileSync('core.yaml','utf8')); if (!cfg.validators?.[pluginName]) throw new Error(`plugin ${pluginName} not registered on this peer`); Type guard
function pluginRegistered(cfg, name) { return !!cfg?.validators && Object.prototype.hasOwnProperty.call(cfg.validators, name); } Try / catch
try { validate(tx); } catch (err) { if (/plugin with name .* wasn't found/.test(err.message)) { /* register plugin in core.yaml or use 'vscc' */ } else { throw err; } } Prevention
- Register every custom validation plugin in core.yaml on all validating peers.
- Verify plugin names in definitions against peer config before committing definitions.
- Ship plugin libraries with your peer deployment tooling.
- Keep peer builds consistent across the channel.
When it happens
Trigger: A chaincode definition names a custom validation plugin (e.g. plugin 'myvscc') that is absent from the peer's core.yaml validators map or was not registered via the plugin registry — hit at validation time for the first tx of that chaincode.
Common situations: Deploying a chaincode with a custom vscc plugin on a peer whose core.yaml lacks the validators.<name> entry; typo in plugin name in the definition; plugin .so/library not present on the peer host; definition approved on one peer image that lacks the plugin used by the channel.
Related errors
- chaincode definition for
- 1 - Error loading MSP configuration for org
- block numbers not maintained in index
- cannot init crypto, specified path
- cannot init crypto, specified path
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/0f221e7764fc8f23.
Report an issue: GitHub.
Appendix: source
Thrown at core/committer/txvalidator/v20/plugindispatcher/plugin_validator.go:146
plugin, err := pv.getOrCreatePlugin(ctx)
if err != nil {
return &validation.ExecutionFailureError{
Reason: fmt.Sprintf("plugin with name %s couldn't be used: %v", ctx.PluginName, err),
}
}
err = plugin.Validate(ctx.Block, ctx.Namespace, ctx.Seq, 0, txvalidatorplugin.SerializedPolicy(ctx.Policy))
validityStatus := "valid"
if err != nil {
validityStatus = fmt.Sprintf("invalid: %v", err)
}
logger.Debug("Transaction", ctx.TxID, "appears to be", validityStatus)
return err
}
func (pv *PluginValidator) getOrCreatePlugin(ctx *Context) (validation.Plugin, error) {
pluginFactory := pv.FactoryByName(txvalidatorplugin.Name(ctx.PluginName))
if pluginFactory == nil {
return nil, errors.Errorf("plugin with name %s wasn't found", ctx.PluginName)
}
pluginsByChannel := pv.getOrCreatePluginChannelMapping(txvalidatorplugin.Name(ctx.PluginName), pluginFactory)
return pluginsByChannel.createPluginIfAbsent(ctx.Channel)
}
func (pv *PluginValidator) getOrCreatePluginChannelMapping(plugin txvalidatorplugin.Name, pf validation.PluginFactory) *pluginsByChannel {
pv.Lock()
defer pv.Unlock()
endorserChannelMapping, exists := pv.pluginChannelMapping[plugin]
if !exists {
endorserChannelMapping = &pluginsByChannel{
pluginFactory: pf,
channels2Plugins: make(map[string]validation.Plugin),
pv: pv,
}
pv.pluginChannelMapping[plugin] = endorserChannelMapping
}View on GitHub (pinned to 2736b63f8f)