protoc-gen-validate
A protoc plugin that generates polyglot message validators, enforcing constraints Protocol Buffers alone can't express.
Repository Health
Technical Analysis
protoc-gen-validate (PGV) is a protoc plugin that turns declarative constraint annotations on .proto fields into generated Validate() methods for Go, Java, and (partially) C++. Because protobuf’s type system only guarantees shape, not semantics, PGV fills the gap: developers annotate messages with rules like (validate.rules).string.email = true or (validate.rules).uint64.gt = 999, and the plugin emits idiomatic validation code alongside the normal generated message types.
The project is maintained by Buf (originally created at Lyft, later hosted under the envoyproxy GitHub org for module-path stability) and is now in maintenance mode — its authors recommend new projects adopt the successor project, protovalidate, which addresses PGV’s design limitations. PGV nonetheless remains widely deployed across gRPC services, including Envoy itself, and continues to receive maintenance releases.
What You Get
- A
protoc-gen-validatebinary that runs as a standard protoc plugin alongside language-native generators - A shared
validate.protoextension schema defining constraint rules for every protobuf scalar, message, and well-known type - Generated
Validate()methods in Go, Java, or C++ that raise descriptive errors identifying exactly which field failed which rule - Cross-language rule parity — the same .proto annotations produce equivalent validation behavior regardless of target language
- Support for nested message validation, oneofs, repeated/map fields, and well-known types like Duration, Timestamp, and wrapper types
Common Use Cases
- Validating incoming gRPC request messages at the service boundary before business logic runs
- Enforcing field-level constraints (ranges, regex patterns, required nested messages) across polyglot microservices sharing one .proto schema
- Replacing hand-written boilerplate validation logic in generated protobuf message wrappers
- Adding email/UUID/pattern validation to API request DTOs generated from protobuf definitions
Under The Hood
Architecture
PGV is built on protoc-gen-star (pgs), a framework for writing protoc plugins that hides raw CodeGeneratorRequest handling behind a typed AST of packages, files, and messages. main.go wires up a single module.Validator() module and registers it with pgs.Init(...).RegisterModule(...).RegisterPostProcessor(pgsgo.GoFmt()); module/validate.go’s Module.Execute walks every target file’s messages, calls CheckRules (in module/checker.go) to read the validate.rules/validate.disabled protobuf extensions off each field and message, then dispatches to per-language, per-type Go templates under templates/go, templates/java, and templates/shared to emit the actual validator source. Constraint types themselves are defined once, language-agnostically, in validate/validate.proto and compiled to validate/validate.pb.go, so every target language reads the same rule schema. What breaks if this changes: altering the validate.proto extension numbers or FieldRules oneof shape would require regenerating and re-releasing every language’s templates in lockstep, since Go/Java/C++ all deserialize the identical wire-compatible extension.
Tech Stack
The module targets Go 1.24 and depends on github.com/lyft/protoc-gen-star/v2 for the plugin framework and google.golang.org/protobuf for core protobuf runtime types; there are no web/ORM frameworks since this is a codegen tool, not a service. The build is dual-tracked: a Go-native Makefile/go build path for the protoc-gen-validate-go/-java/-cpp binaries under cmd/, and a parallel Bazel build (WORKSPACE, BUILD.bazel files, dependencies.bzl) used for the cross-language conformance harness and CI. Releases are cut via GoReleaser (.goreleaser.yaml) and published as GitHub Releases plus a Java artifact via Maven (.github/workflows/maven-release.yaml).
Code Quality
There are no conventional Go _test.go unit tests in the repository; instead, correctness is verified through a custom multi-language conformance harness (tests/harness) that compiles a shared set of annotated .proto test-case files (tests/harness/cases/*.proto) through the Go, Java, and C++ generators and an executor package that runs the generated validators against expected pass/fail fixtures. Code style is enforced via .golangci.yml (gofumpt, gocritic, govet with shadow-checking, misspell), and CI (.github/workflows/ci.yaml) runs on every push. Error handling in the plugin itself favors pgs.Module’s Assert/Fail/CheckErr helpers, which surface plugin misconfiguration as protoc-level failures rather than silently swallowing them.
API Design
Developer-facing surface area is intentionally small: a single protobuf extension (validate.rules on fields, validate.disabled on messages) and one lang plugin parameter control all behavior, so integrating PGV into an existing protoc invocation is a one-line addition alongside the language-native generator. The generated Validate() error method follows the same naming/signature convention every consumer already expects from protobuf-generated code, minimizing new API surface to learn. The README is unusually thorough for a codegen tool, documenting every rule type per protobuf field type with runnable examples, though the project’s own maintenance-mode notice steers newcomers toward protovalidate for new work.
Used by 2 apps in this directory
Rill
Analytics · Data Engineering
The fastest BI tool for humans and agents — define metrics, models, and dashboards as code and query them instantly on ClickHouse or DuckDB.
ZITADEL
Authentication
Open-source, API-first identity platform delivering multi-tenancy, Passkeys, OIDC, SAML, and SCIM without vendor lock-in.