Skip to content
Latchkey

protoc "Explicit 'optional' labels are disallowed" in CI

proto3 field presence with optional was stabilized in protoc 3.15. An older compiler rejects the optional label, so a CI runner with a lagging protoc fails on a file that compiles locally.

What this error means

protoc fails with "Explicit 'optional' labels are disallowed in the Proto3 syntax. To define 'optional' fields in Proto3, simply remove the 'optional' label ..." on an older protoc.

protoc
api/v1/user.proto:8:3: Explicit 'optional' labels are disallowed in the Proto3 syntax.
To define 'optional' fields in Proto3, simply remove the 'optional' label, as fields
are 'optional' by default.

Common causes

protoc predates proto3 optional support

proto3 explicit optional needs protoc 3.15 or newer; a runner with an older apt package or pinned version rejects it.

Version skew between local and CI protoc

Your machine has a modern protoc while CI installs an older one, so the same proto compiles locally but fails in the pipeline.

How to fix it

Upgrade protoc to 3.15 or newer

  1. Install a modern protoc with a setup action instead of the distro package.
  2. Pin the exact version so local and CI agree.
  3. Re-run codegen.
.github/workflows/ci.yml
- uses: arduino/setup-protoc@v3
  with:
    version: '27.2'

Generate with buf, which bundles a current compiler

buf embeds an up-to-date Protocol Buffers compiler, so proto3 optional works without managing a protoc version.

Terminal
buf generate

How to prevent it

  • Pin protoc to a version that supports every feature your protos use.
  • Keep local and CI protoc versions identical.
  • Prefer buf so the compiler version travels with the tool.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →