{"record":{"id":"8839809c84fca7ad","repo":"hyperledger/fabric","slug":"illegal-file-name-in-payload-s","errorCode":null,"errorMessage":"illegal file name in payload: %s","messagePattern":"illegal file name in payload: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/platforms/golang/platform.go","lineNumber":96,"sourceCode":"\tgr, err := gzip.NewReader(is)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failure opening codepackage gzip stream: %s\", err)\n\t}\n\n\tre := regexp.MustCompile(`^(src|META-INF)/`)\n\ttr := tar.NewReader(gr)\n\tfor {\n\t\theader, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// maintain check for conforming paths for validation\n\t\tif !re.MatchString(header.Name) {\n\t\t\treturn fmt.Errorf(\"illegal file name in payload: %s\", header.Name)\n\t\t}\n\n\t\t// only files and directories; no links or special files\n\t\tmode := header.FileInfo().Mode()\n\t\tif mode&^(os.ModeDir|0o777) != 0 {\n\t\t\treturn fmt.Errorf(\"illegal file mode in payload: %s\", header.Name)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Directory constant copied from tar package.\nconst c_ISDIR = 0o40000\n\n// Default compression to use for production. Test packages disable compression.\nvar gzipCompressionLevel = gzip.DefaultCompression\n","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/platforms/golang/platform.go#L78-L114","documentation":"ValidateCodePackage iterates over the tar entries of a chaincode package and checks each archive header name against a regex of allowed characters/paths. If a tar entry name does not conform, this error is returned to reject packages that could contain path traversal or unsafe file names.","triggerScenarios":"Calling ValidateCodePackage with a tar.gz code package containing an entry whose Name fails the re.MatchString check, e.g. names with illegal characters, absolute paths, or '..' segments.","commonSituations":"Developers hand-crafting chaincode deployment packages, using non-Go tooling (Windows tar, 7-zip) that emits backslash-separated or absolute entry names, or packaging symlinks/odd paths.","solutions":["Repackage the chaincode with relative, slash-separated paths using tar (no leading '/', no '..').","Verify each entry name with the same regex (^[^:\\\\]+ or project's pattern) before packaging.","Build the package via the SDK/peer lifecycle tooling rather than manual tar.","Remove entries with Windows drive letters or backslashes; re-create the archive on Linux."],"exampleFix":"// before: tar created on Windows with backslash paths\ntar -cf code.tar.gz src\\main.go\n// after\ntar -czf code.tar.gz src/main.go","handlingStrategy":"validation","validationCode":"import (\"archive/tar\"; \"regexp\"; \"bytes\")\nfunc entryNamesOK(tgz []byte) error {\n\tre := regexp.MustCompile(`^[^:\\\\]+(/[^:\\\\]+)*$`)\n\tgr, _ := gzip.NewReader(bytes.NewReader(tgz))\n\ttr := tar.NewReader(gr)\n\tfor {\n\t\th, err := tr.Next()\n\t\tif err == io.EOF { return nil }\n\t\tif err != nil { return err }\n\t\tif !re.MatchString(h.Name) { return fmt.Errorf(\"bad name: %s\", h.Name) }\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err := platform.ValidateCodePackage(pkg); err != nil {\n\tif strings.Contains(err.Error(), \"illegal file name in payload\") {\n\t\t// repackage archive with clean relative paths\n\t}\n}","preventionTips":["Build packages with relative, slash-separated entry names","Avoid Windows tars with backslash names","Run ValidateCodePackage on artifacts before submitting them"],"tags":["chaincode","tar","validation","hyperledger-fabric"],"backgroundTag":"illegal-path-in-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"}