{"record":{"id":"8a4044d9667047da","repo":"hyperledger/fabric","slug":"invalid-deployment-spec","errorCode":null,"errorMessage":"invalid deployment spec","messagePattern":"invalid deployment spec","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/common/ccprovider/cc_statedb_artifacts_provider.go","lineNumber":50,"sourceCode":"\t\t// we can abort the chaincode instantiate/upgrade/install operation.\n\t\tccproviderLogger.Infof(\"Error while loading installation package for ccNameVersion=%s Err=%s\", ccNameVersion, err)\n\t\treturn false, nil, nil\n\t}\n\n\tstatedbArtifactsTar, err = ExtractStatedbArtifactsFromCCPackage(ccpackage)\n\treturn true, statedbArtifactsTar, err\n}\n\n// ExtractStatedbArtifactsFromCCPackage extracts the statedb artifacts from the code package tar and create a statedb artifact tar.\n// The state db artifacts are expected to contain state db specific artifacts such as index specification in the case of couchdb.\n// This function is called during chaincode instantiate/upgrade (from above), and from install, so that statedb artifacts can be created.\nfunc ExtractStatedbArtifactsFromCCPackage(ccpackage CCPackage) (statedbArtifactsTar []byte, err error) {\n\tcds := ccpackage.GetDepSpec()\n\n\tmetaprov, err := MetadataAsTarEntries(cds.CodePackage)\n\tif err != nil {\n\t\tccproviderLogger.Infof(\"invalid deployment spec: %s\", err)\n\t\treturn nil, errors.New(\"invalid deployment spec\")\n\t}\n\treturn metaprov, nil\n}\n\n// ExtractFileEntries extract file entries from the given `tarBytes`. A file entry is included in the\n// returned results only if it is located in a directory under the indicated databaseType directory\n// Example for chaincode indexes:\n// \"META-INF/statedb/couchdb/indexes/indexColorSortName.json\"\n// Example for collection scoped indexes:\n// \"META-INF/statedb/couchdb/collections/collectionMarbles/indexes/indexCollMarbles.json\"\n// An empty string will have the effect of returning all statedb metadata.  This is useful in validating an\n// archive in the future with multiple database types\nfunc ExtractFileEntries(tarBytes []byte, databaseType string) (map[string][]*TarFileEntry, error) {\n\tindexArtifacts := map[string][]*TarFileEntry{}\n\ttarReader := tar.NewReader(bytes.NewReader(tarBytes))\n\tfor {\n\t\thdr, err := tarReader.Next()\n\t\tif err == io.EOF {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/common/ccprovider/cc_statedb_artifacts_provider.go#L32-L68","documentation":"ExtractStatedbArtifactsFromCCPackage derives statedb (CouchDB) index artifacts from the chaincode package's code package via MetadataAsTarEntries. If the metadata extraction fails — typically because the code package is not a valid tar or contains no META-INF/statedb artifacts — this error is returned (the detailed cause is only logged).","triggerScenarios":"Calling ExtractStatedbArtifactsFromCCPackage with a CCPackage whose GetDepSpec() returns a spec with a nil/empty or non-tar CodePackage, e.g. a chaincode installed without the source packed as a tar.gz, or corrupted install package bytes.","commonSituations":"Chaincode installed with `peer chaincode install` where the input was not a valid archive; index artifacts missing under META-INF/statedb/couchdb/indexes; package corrupted during upload; Go chaincode packaged without -s/--source handling producing empty code package.","solutions":["Repackage and reinstall the chaincode ensuring the code package is a valid tar.gz containing META-INF/statedb/couchdb/indexes/*.json for CouchDB indexes","Check the ccproviderLogger output ('invalid deployment spec: %s') for the underlying tar-extraction cause and fix that first","Verify the chaincode source directory layout: indexes must live under META-INF/statedb/couchdb/indexes relative to the chaincode root","Confirm the CCPackage passed in was loaded successfully (GetDepSpec non-nil, CodePackage non-empty) before extracting artifacts"],"exampleFix":"// before\nartifacts, err := ccprovider.ExtractStatedbArtifactsFromCCPackage(ccpack) // ccpack.CodePackage empty\n// after\nif ccpack.GetDepSpec() == nil || len(ccpack.GetDepSpec().CodePackage) == 0 {\n    return errors.New(\"chaincode package has no code package; reinstall with valid tar.gz source\")\n}\nartifacts, err := ccprovider.ExtractStatedbArtifactsFromCCPackage(ccpack)","handlingStrategy":"validation","validationCode":"depspec := ccpack.GetDepSpec()\nif depspec == nil || len(depspec.CodePackage) == 0 {\n    return errors.New(\"no code package; reinstall chaincode with valid tar.gz source\")\n}\nartifacts, err := ccprovider.ExtractStatedbArtifactsFromCCPackage(ccpack)","typeGuard":"func hasCodePackage(c ccprovider.CCPackage) bool {\n    d := c.GetDepSpec()\n    return d != nil && len(d.CodePackage) > 0\n}","tryCatchPattern":"artifacts, err := ccprovider.ExtractStatedbArtifactsFromCCPackage(ccpack)\nif err != nil {\n    if err.Error() == \"invalid deployment spec\" {\n        return fmt.Errorf(\"code package is not a valid tar or has no statedb metadata; see ccprovider log for cause: %w\", err)\n    }\n    return err\n}","preventionTips":["Package chaincode source as a proper tar.gz with META-INF/statedb/couchdb/indexes for CouchDB indexes","Check the ccproviderLogger detail line for the real underlying error","Verify install packages with tar -tzf before installing"],"tags":["hyperledger-fabric","statedb","couchdb-index","tar","chaincode-package"],"backgroundTag":"invalid-chaincode-package","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"}