grpc-ecosystem/grpc-gateway · error

failed to unmarshal code generator request: %w

Error message

failed to unmarshal code generator request: %w

What it means

ParseRequest wraps proto.Unmarshal failures when the bytes read from the reader are not a valid CodeGeneratorRequest protobuf. The plugin received input that cannot be decoded as the expected pluginpb.CodeGeneratorRequest message.

Source

Thrown at internal/codegenerator/parse_req.go:19

package codegenerator

import (
	"fmt"
	"io"

	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/types/pluginpb"
)

// ParseRequest parses a code generator request from a proto Message.
func ParseRequest(r io.Reader) (*pluginpb.CodeGeneratorRequest, error) {
	input, err := io.ReadAll(r)
	if err != nil {
		return nil, fmt.Errorf("failed to read code generator request: %w", err)
	}
	req := new(pluginpb.CodeGeneratorRequest)
	if err := proto.Unmarshal(input, req); err != nil {
		return nil, fmt.Errorf("failed to unmarshal code generator request: %w", err)
	}
	return req, nil
}

View on GitHub (pinned to a58a4436a3)

Solutions

  1. Ensure the input really is a serialized CodeGeneratorRequest — capture one via protoc and pipe that exact file
  2. Regenerate/capture with matching protoc and google.golang.org/protobuf versions (go mod tidy; update protoc)
  3. In tests, build a valid pluginpb.CodeGeneratorRequest and proto.Marshal it instead of using raw strings

Example fix

// before
req, err := codegenerator.ParseRequest(strings.NewReader("not protobuf"))
// after
data, _ := proto.Marshal(&pluginpb.CodeGeneratorRequest{})
req, err := codegenerator.ParseRequest(bytes.NewReader(data))
Defensive patterns

Strategy: try-catch

Validate before calling

// sanity check before unmarshal in custom code
input, err := io.ReadAll(r)
if err != nil || len(input) == 0 {
    return fmt.Errorf("empty or unreadable plugin input")
}

Try / catch

req, err := codegenerator.ParseRequest(r)
if err != nil {
    if strings.Contains(err.Error(), "failed to unmarshal code generator request") {
        grpclog.Fatalf("input is not a CodeGeneratorRequest: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Running a protoc plugin binary directly with garbage/empty stdin; piping a text or truncated file instead of the serialized request; protoc/plugin version mismatch producing an undecodable payload; passing the wrong proto message type from a custom harness.

Common situations: Manual debugging of plugin binaries without a valid request.bin; writing plugin tests that pass hand-rolled bytes; older protoc generating requests incompatible with the plugin's protobuf runtime expectations.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02). Data as JSON: /api/errors/0de3ad985f9938d8. Report an issue: GitHub.