{"record":{"id":"6f0d8ef6414b21b7","repo":"hyperledger/fabric","slug":"chaincode-definition-for-s-is-invalid-plugin-f","errorCode":null,"errorMessage":"chaincode definition for [%s] is invalid, plugin field must be set","messagePattern":"chaincode definition for \\[(.+?)\\] is invalid, plugin field must be set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"core/committer/txvalidator/v20/plugindispatcher/dispatcher.go","lineNumber":255,"sourceCode":"func (v *dispatcherImpl) getCDataForCC(channelID, ccid string) (string, []byte, error) {\n\tqe, err := v.ler.NewQueryExecutor()\n\tif err != nil {\n\t\treturn \"\", nil, errors.WithMessage(err, \"could not retrieve QueryExecutor\")\n\t}\n\tdefer qe.Done()\n\n\tplugin, args, unexpectedErr, validationErr := v.lcr.ValidationInfo(channelID, ccid, qe)\n\tif unexpectedErr != nil {\n\t\treturn \"\", nil, &commonerrors.VSCCInfoLookupFailureError{\n\t\t\tReason: fmt.Sprintf(\"Could not retrieve state for chaincode %s, error %s\", ccid, unexpectedErr),\n\t\t}\n\t}\n\tif validationErr != nil {\n\t\treturn \"\", nil, validationErr\n\t}\n\n\tif plugin == \"\" {\n\t\treturn \"\", nil, errors.Errorf(\"chaincode definition for [%s] is invalid, plugin field must be set\", ccid)\n\t}\n\n\tif len(args) == 0 {\n\t\treturn \"\", nil, errors.Errorf(\"chaincode definition for [%s] is invalid, policy field must be set\", ccid)\n\t}\n\n\treturn plugin, args, nil\n}\n\n// GetInfoForValidate gets the ChaincodeInstance(with latest version) of tx, validation plugin and policy\nfunc (v *dispatcherImpl) GetInfoForValidate(chdr *common.ChannelHeader, ccID string) (string, []byte, error) {\n\t// obtain name of the validation plugin and the policy\n\tplugin, args, err := v.getCDataForCC(chdr.ChannelId, ccID)\n\tif err != nil {\n\t\tlogger.Errorf(\"Unable to get chaincode data from ledger for txid %s, due to %s\", chdr.TxId, err)\n\t\treturn \"\", nil, err\n\t}\n\treturn plugin, args, nil","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/committer/txvalidator/v20/plugindispatcher/dispatcher.go#L237-L273","documentation":"getCDataForCC (invoked via GetInfoForValidate during validation) fetched the chaincode definition from the lifecycle/LSCC, and its validation-plugin field is empty. Since V20 validation requires every chaincode definition to name a validation plugin (default 'vscc'), Fabric returns this error meaning the definition on the ledger is incomplete or was written without required fields.","triggerScenarios":"Chaincode definition stored on-chain (via LCCS JSON args or new lifecycle) has an empty plugin name when Dispatch→GetInfoForValidate→getCDataForCC reads it — e.g. an LSCC record hand-written with missing plugin field, or a corrupted/incomplete upgrade.","commonSituations":"Manually edited or legacy LSCC records migrated from older networks without the plugin field; failed/partial chaincode upgrades leaving incomplete definitions; custom lifecycle implementations that skip plugin defaults.","solutions":["Set the plugin field explicitly (use default 'vscc' for endorsement-policy validation) in the chaincode definition and re-approve/upgrade.","Re-issue the chaincode definition transaction with all required fields populated.","Fix the lifecycle code that persisted the definition so it defaults plugin to 'vscc' when unset.","Restore the definition from a healthy backup/orderer snapshot if ledger data is corrupt."],"exampleFix":"// before (definition JSON)\n{ \"Name\":\"mycc\", \"Version\":\"1.0\", \"Policy\": ... }  // plugin missing\n// after\n{ \"Name\":\"mycc\", \"Version\":\"1.0\", \"Plugin\":\"vscc\", \"Policy\": ... }","handlingStrategy":"validation","validationCode":"const def = getChaincodeDefinition(name, version); if (!def.plugin) throw new Error(`definition for ${name} missing plugin; expected 'vscc' or custom plugin`);","typeGuard":"function hasPlugin(def) { return typeof def?.plugin === 'string' && def.plugin.length > 0; }","tryCatchPattern":"try { getInfoForValidate(); } catch (err) { if (/plugin field must be set/.test(err.message)) { /* re-issue definition with plugin set */ } else { throw err; } }","preventionTips":["Always set Plugin: 'vscc' (or your custom plugin) in definitions.","Never hand-edit LSCC ledger records.","Use standard lifecycle commands for approve/commit.","Back up and verify definitions after upgrades."],"tags":["hyperledger-fabric","lifecycle","validation-plugin","configuration"],"backgroundTag":"missing-validation-plugin","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}