grpc-ecosystem/grpc-gateway · info · errNoTargetService

no target service defined in the file

Error message

no target service defined in the file

What it means

errNoTargetService is the sentinel error returned by the generators when a .proto file contains no service definitions to render. genopenapi/Generate and gengateway's generator skip such files, and callers use errors.Is(err, errNoTargetService) to log-and-continue instead of failing the whole run. It is not a fatal condition: a proto file without services simply produces no gateway/OpenAPI output.

Source

Thrown at protoc-gen-openapiv2/internal/genopenapi/generator.go:26

	"path/filepath"
	"reflect"
	"sort"
	"strings"

	"github.com/grpc-ecosystem/grpc-gateway/v2/internal/descriptor"
	gen "github.com/grpc-ecosystem/grpc-gateway/v2/internal/generator"
	openapioptions "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
	"go.yaml.in/yaml/v3"
	statuspb "google.golang.org/genproto/googleapis/rpc/status"
	"google.golang.org/grpc/grpclog"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protodesc"
	"google.golang.org/protobuf/types/descriptorpb"
	"google.golang.org/protobuf/types/known/anypb"
	"google.golang.org/protobuf/types/pluginpb"
)

var errNoTargetService = errors.New("no target service defined in the file")

type generator struct {
	reg    *descriptor.Registry
	format Format
}

type wrapper struct {
	fileName string
	swagger  *openapiSwaggerObject
}

type GeneratorOptions struct {
	Registry       *descriptor.Registry
	RecursiveDepth int
}

// New returns a new generator which generates grpc gateway files.
func New(reg *descriptor.Registry, format Format) gen.Generator {

View on GitHub (pinned to a58a4436a3)

Solutions

  1. Restrict the plugin invocation to proto files that contain service definitions (pass only service protos as arguments).
  2. If the file intentionally has no service, ignore the message — with grpclog V(1) enabled it is informational only and generation succeeds.
  3. Add a `service` block to the proto if output was expected from it.
  4. In custom code, treat this case with errors.Is(err, errNoTargetService) and skip rather than abort.

Example fix

// before
protoc --grpc-gateway_out=. ./proto/*.proto   # includes message-only files
// after
protoc --grpc-gateway_out=. ./proto/service_foo.proto ./proto/service_bar.proto
Defensive patterns

Strategy: validation

Validate before calling

// shell: only pass protos that declare services to the plugins
grep -L '^service ' proto/*.proto   # these will trigger errNoTargetService; exclude them

Try / catch

// Go
if errors.Is(err, errNoTargetService) {
    grpclog.Infof("%s: skipped (no services)", file.GetName())
    return nil
}

Prevention

When it happens

Trigger: Running protoc-gen-grpc-gateway or protoc-gen-openapiv2 over a .proto file that declares only messages/enums/imports and no `service` block; Generate/applyTemplate/g.generate detect zero services and return this sentinel.

Common situations: Passing a whole directory of protos (or an include path with common/model protos) to the plugin so non-service files are processed; splitting services out of a proto that previously had one; generating against dependency-only protos.

Related errors


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