{"record":{"id":"0f9e2d4da1c19191","repo":"grafana/k6","slug":"couldn-t-unmarshal-protoset-file-s-w","errorCode":null,"errorMessage":"couldn't unmarshal protoset file %s: %w","messagePattern":"couldn't unmarshal protoset file (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/grpc/client.go","lineNumber":118,"sourceCode":"\tif initEnv == nil {\n\t\treturn nil, errors.New(\"missing init environment\")\n\t}\n\n\tabsFilePath := initEnv.GetAbsFilePath(protosetPath)\n\tfdsetFile, err := initEnv.FileSystems[\"file\"].Open(absFilePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"couldn't open protoset: %w\", err)\n\t}\n\n\tdefer func() { _ = fdsetFile.Close() }()\n\tfdsetBytes, err := io.ReadAll(fdsetFile)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"couldn't read protoset: %w\", err)\n\t}\n\n\tfdset := &descriptorpb.FileDescriptorSet{}\n\tif err = proto.Unmarshal(fdsetBytes, fdset); err != nil {\n\t\treturn nil, fmt.Errorf(\"couldn't unmarshal protoset file %s: %w\", protosetPath, err)\n\t}\n\n\treturn c.convertToMethodInfo(fdset)\n}\n\n// Note: this function was lifted from `lib/options.go`\nfunc decryptPrivateKey(key, password []byte) ([]byte, error) {\n\tblock, _ := pem.Decode(key)\n\tif block == nil {\n\t\treturn nil, errors.New(\"failed to decode PEM key\")\n\t}\n\n\tblockType := block.Type\n\tif blockType == \"ENCRYPTED PRIVATE KEY\" {\n\t\treturn nil, errors.New(\"encrypted pkcs8 formatted key is not supported\")\n\t}\n\t/*\n\t   Even though `DecryptPEMBlock` has been deprecated since 1.16.x it is still","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/grpc/client.go#L100-L136","documentation":"grpc.Client.load() read the file bytes but proto.Unmarshal could not decode them as a protobuf-serialized FileDescriptorSet; the error is wrapped as 'couldn't unmarshal protoset file <path>' (internal/js/modules/k6/grpc/client.go:118). The file exists and is readable - its bytes are simply not a protoset. The offending path is included in the message.","triggerScenarios":"Passing a .proto source file (plain text) to client.load(); passing a JSON descriptor or a single FileDescriptorProto instead of a set; a protoset corrupted by text-mode transfer (base64/UTF-8 mangling, git media filters).","commonSituations":"Generating descriptors with the wrong protoc invocation (must be --descriptor_set_out, typically with --include_imports); renaming a .proto file to .protoset instead of compiling; binary files mangled through chat tools or copy-paste.","solutions":["Regenerate correctly: protoc --include_imports --descriptor_set_out=service.protoset service.proto","Sanity-check the file: `file service.protoset` should report data, not ASCII text","Or skip the protoset and use server reflection: client.connect(addr, { reflect: true })"],"exampleFix":"# before (produces a .proto text file, not a protoset)\nprotoc --proto_path=. service.proto --descriptor_set_out=service.protoset\n\n# after (binary FileDescriptorSet including imports)\nprotoc --include_imports --proto_path=. service.proto --descriptor_set_out=service.protoset","handlingStrategy":"validation","validationCode":"// cheap guard: a valid protoset is binary protobuf, not .proto text\nconst head = open('./pb/service.protoset');\nif (head.startsWith('syntax') || head.startsWith('//')) {\n  throw new Error('file looks like .proto source; compile with protoc --descriptor_set_out first');\n}\nclient.load('./pb/service.protoset');","typeGuard":null,"tryCatchPattern":"try {\n  client.load(p);\n} catch (e) {\n  if (/couldn't unmarshal protoset/.test(e.message)) {\n    throw new Error(`${p} is not a FileDescriptorSet; regenerate with protoc --include_imports --descriptor_set_out`);\n  }\n  throw e;\n}","preventionTips":["Always compile with --descriptor_set_out (plus --include_imports)","Never rename .proto files into .protoset","Treat protosets as binary in git/CI (no text-mode transfers)"],"tags":["grpc","k6","protobuf","protoset","serialization"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}