# rpc error: code = Internal desc = grpc: error while marshaling: proto: Marshal called with nil

- **ID:** `go/grpc-internal-error-transport`
- **Domain:** go
- **Category:** runtime_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

The gRPC framework failed to marshal the response because a nil message was returned from the handler. The nil propagates to the codec.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| grpc-go 1.60+ | active | — | — |

## Workarounds

1. **** (95% success)
   ```
   Always return a non-nil response or an explicit error from handlers:
func (s *svc) Get(ctx context.Context, req *pb.Req) (*pb.Resp, error) {
    if req == nil {
        return nil, status.Error(codes.InvalidArgument, "nil request")
    }
    return &pb.Resp{...}, nil
}
   ```
2. **** (90% success)
   ```
   Add a server interceptor to detect nil responses early:
func nilGuard(ctx context.Context, req, resp any, info *grpc.UnaryServerInfo, h grpc.UnaryHandler) (any, error) {
    r, err := h(ctx, req)
    if err == nil && r == nil { return nil, status.Error(codes.Internal, "handler returned nil") }
    return r, err
}
   ```

## Dead Ends

- **** — A nil response is a contract violation; a custom codec hides the bug and produces empty/garbage payloads. (85% fail)
- **** — Returning a non-nil but empty message masks the real logic error and clients receive semantically wrong data. (75% fail)
