Skip to content
Latchkey

buf lint: Enforce Proto Style Rules in CI

buf lint validates .proto files against a rule set (DEFAULT, BASIC, STANDARD, or comments) configured in buf.yaml and exits non-zero on any violation.

buf lint catches naming and structural problems before they reach generated code. It is opinionated but configurable, and gives one annotated line per violation.

What it does

buf lint runs every enabled rule against the module. Rule categories are grouped (MINIMAL, BASIC, DEFAULT, STANDARD, COMMENTS, UNARY_RPC); you select categories and exceptions under lint: in buf.yaml. Each violation prints as path:line:col:message and the command exits 100 (non-zero) if any fire.

Common usage

Terminal
buf lint
buf lint --path proto/api/v1
buf lint --error-format=github-actions

# buf.yaml
# version: v2
# lint:
#   use:
#     - DEFAULT
#   except:
#     - PACKAGE_VERSION_SUFFIX

Flags and options

Flag / configWhat it does
--path <path>Lint only the given files or directories
--error-format <fmt>text (default), json, msvs, or github-actions
--config <data>Inline or path config override for buf.yaml
lint.useCategories or rules to enable (e.g. DEFAULT, STANDARD)
lint.exceptRules to disable (e.g. PACKAGE_VERSION_SUFFIX)
lint.ignoreFiles or dirs excluded from linting

In CI

Run buf lint before buf generate so style is enforced on source, not on generated output. --error-format=github-actions turns each violation into an inline PR annotation. Use lint.ignore for vendored third-party protos you do not control.

Common errors in CI

Typical violations: "Field name "userId" should be lower_snake_case", "Service name "userservice" should be PascalCase", "Files with package "acme.api" must be within a directory "acme/api" relative to root" (PACKAGE_DIRECTORY_MATCH), and "Enum zero value should be suffixed with _UNSPECIFIED". A config error like "Failure: invalid lint rule "FOO"" means a misspelled rule in lint.use.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →