Buf Issues#
Troubleshooting guide for Protocol Buffers tooling issues with Buf.
Installation & Setup#
buf: command not found#
exec: "buf": executable file not found in $PATH
Fix: Install Buf via APX or manually:
# Preferred — uses pinned version from apx.lock
apx fetch
# Or install globally
brew install bufbuild/buf/buf
# Verify
buf --version
Wrong Buf version#
Warning: buf version 1.28.0 does not match pinned version 1.47.2
Fix: APX pins tool versions in apx.lock. Use apx fetch to download the correct version, which is cached in .apx-tools/.
Lint Failures#
PACKAGE_VERSION_SUFFIX#
proto/payments/ledger/v1/ledger.proto:3:1:
Package name "payments.ledger" should have a version suffix.
Fix: Include the version in the proto package:
package payments.ledger.v1; // ✔
// not:
package payments.ledger; // ✘
FIELD_LOWER_SNAKE_CASE#
Field name "userName" should be lower_snake_case.
Fix: Use snake_case for field names:
string user_name = 1; // ✔
// not:
string userName = 1; // ✘
SERVICE_SUFFIX#
Service name "Ledger" should have suffix "Service".
Fix:
service LedgerService { ... } // ✔
RPC_REQUEST_RESPONSE_UNIQUE#
RPC "GetUser" request type "GetUserRequest" is also used by RPC "ListUsers".
Fix: Each RPC should have unique request and response types.
Disabling specific lint rules#
Configure exceptions in buf.yaml:
version: v2
lint:
use:
- DEFAULT
except:
- FIELD_LOWER_SNAKE_CASE # if you have legacy fields
Note: APX’s
apx policy checkmay enforce required lint rules that overridebuf.yamlexceptions.
Breaking Change Failures#
FIELD_NO_DELETE#
Previously present field "2" with name "email" on message "User" was deleted.
Fix: Don’t remove fields — mark them as reserved instead:
message User {
string name = 1;
reserved 2; // was: string email = 2;
reserved "email";
string email_address = 3; // new field with new number
}
FIELD_SAME_TYPE#
Field "1" with name "id" on message "User" changed type from "string" to "int64".
Fix: Field types cannot change. Add a new field with the new type and deprecate the old one.
ENUM_VALUE_NO_DELETE#
Previously present enum value "2" with name "STATUS_ACTIVE" was deleted.
Fix: Reserve deleted enum values:
enum Status {
STATUS_UNSPECIFIED = 0;
reserved 2; // was STATUS_ACTIVE
STATUS_ENABLED = 3;
}
False positive breaking changes#
If apx breaking reports changes that aren’t actually breaking:
# Check the baseline reference
apx breaking --against origin/main --verbose
# Verify you're comparing against the right baseline
git log --oneline origin/main..HEAD
Common causes of false positives:
Comparing against the wrong baseline branch
buf.yamlversion change (v1 vs v2) causes structural differencesReordering fields (field numbers didn’t change, but file diff triggers detection)
go_package Warnings#
go_package does not match canonical path#
Warning: go_package "github.com/myorg/myrepo/gen/proto/payments/ledger/v1"
does not match canonical path "github.com/acme-corp/apis/proto/payments/ledger/v1"
Cause: The go_package option in your .proto files doesn’t match the import path that consumers will use after publishing to the canonical repo.
Fix: Update the go_package option:
option go_package = "github.com/acme-corp/apis/proto/payments/ledger/v1";
The canonical path is derived from:
canonical_repoinapx.yaml(or--canonical-repoflag)The API ID path
Check what APX expects:
apx inspect identity proto/payments/ledger/v1
apx explain go-path proto/payments/ledger/v1
buf.yaml Configuration#
v1 vs v2 format#
Buf v1 and v2 have different buf.yaml schemas. APX works with both but prefers v2:
# v2 (recommended)
version: v2
lint:
use:
- DEFAULT
breaking:
use:
- FILE
# v1 (legacy)
version: v1
lint:
use:
- DEFAULT
breaking:
use:
- FILE
Missing buf.yaml#
If no buf.yaml exists, Buf uses defaults. APX recommends creating one for consistent behavior:
buf config init
Dependencies in buf.yaml#
If your protos import well-known types or other Buf modules:
version: v2
deps:
- buf.build/googleapis/googleapis
- buf.build/grpc/grpc
Then run:
buf dep update
Performance#
Slow lint/breaking checks#
Cause: Buf scans the entire proto tree by default.
Fix: Scope checks to a specific path:
apx lint proto/payments/ledger/v1/
apx breaking proto/payments/ledger/v1/ --against HEAD^
Debugging#
# Verbose output from APX (shows buf invocations)
apx lint --verbose
# Run buf directly for deeper debugging
buf lint proto/payments/ledger/v1/ --error-format=json
buf breaking proto/payments/ledger/v1/ --against .git#branch=main
# Check buf configuration
buf config ls-lint-rules
buf config ls-breaking-rules
See Also#
Validation Commands —
apx lint,apx breakingreferenceCode Generation Troubleshooting —
buf generateissuesCommon Errors — general error reference