OpenAPITools/openapi-generator · error · ProtoBufIndexComputationException
Generated field number is in reserved range (19000, 19999).
Error message
Generated field number is in reserved range (19000, 19999).
What it means
The protobuf-schema generator does not let you write field numbers in the .proto output; it derives them deterministically from each property name via Math.abs(name.hashCode() % 536870911). Protocol Buffers reserves field numbers 19000-19999 for the protobuf implementation itself, so when a computed hash lands in that window the generator aborts with ProtoBufIndexComputationException instead of emitting an invalid .proto file that protoc would reject.
Source
Thrown at modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ProtobufSchemaCodegen.java:1847
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
Schema inner = ModelUtils.getSchemaItems(p);
return getSchemaType(p) + "[" + getTypeDeclaration(inner) + "]";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = ModelUtils.getAdditionalProperties(p);
return getSchemaType(p) + "<string, " + getTypeDeclaration(inner) + ">";
}
return super.getTypeDeclaration(p);
}
private int generateFieldNumberFromString(String name) throws ProtoBufIndexComputationException {
// Max value from developers.google.com/protocol-buffers/docs/proto3#assigning_field_numbers
int fieldNumber = Math.abs(name.hashCode() % 536870911);
if (19000 <= fieldNumber && fieldNumber <= 19999) {
LOGGER.error("Generated field number is in reserved range (19000, 19999) for %s, %d", name, fieldNumber);
throw new ProtoBufIndexComputationException("Generated field number is in reserved range (19000, 19999).");
}
return fieldNumber;
}
/**
* Extracts enum properties from models and creates separate enum model files.
* Also adds imports to the parent models for the extracted enums.
*
* @param objs the models map containing all models
* @return the modified models map with extracted enum models added
*/
private ModelsMap extractEnumsToSeparateFiles(ModelsMap objs) {
List<Map<String, String>> enumImports = new ArrayList<>();
Map<String, CodegenModel> extractedEnums = this.extractEnums(objs);
for (String enumName : extractedEnums.keySet()) {
// Add an import for this enum to the parent model
String enumImportPath = toModelImport(toModelName(enumName));View on GitHub (pinned to fcec517be3)
Solutions
- Rename the offending property in the OpenAPI spec (the error log line prints the name and number); any rename changes the hash and moves the number out of 19000-19999
- Pre-compute the field number for every property name (abs(javaHash(name) % 536870911)) to find all colliding names before generation, then rename each one
- If the wire name must not change, introduce a wrapper/rename at the API layer or maintain the .proto by hand instead of using -g protobuf-schema
- Report/upvote the issue on openapi-generator GitHub so explicit field numbers (e.g. via a vendor extension) get supported
Example fix
# before: spec property whose hash lands in 19000-19999
components:
schemas:
Pet:
properties:
keyCode: # abs(hashCode % 536870911) in reserved range -> generation fails
type: string
# after: rename the property (wire name changes, hash moves out of range)
components:
schemas:
Pet:
properties:
keyCodeValue:
type: string Defensive patterns
Strategy: validation
Validate before calling
# Pre-check every property name against the generator's field-number hash (Python):
def java_hash(s: str) -> int:
h = 0
for c in s:
h = (31 * h + ord(c)) & 0xFFFFFFFF
if h >= 0x80000000:
h -= 0x100000000
return h
def reserved(name: str) -> bool:
return 19000 <= abs(java_hash(name) % 536870911) <= 19999
bad = [p for p in all_property_names(spec) if reserved(p)]
assert not bad, f'rename these properties, they hash into 19000-19999: {bad}' Try / catch
try {
new DefaultGenerator().opts(clientOptInput).generate();
} catch (ProtoBufIndexComputationException e) {
// log the property name from the preceding LOGGER.error line and fail the build fast
throw new IllegalStateException('protobuf field number reserved-range collision, rename the reported property', e);
} Prevention
- Run the hash pre-check in CI for every spec change before invoking -g protobuf-schema
- Treat a protobuf-schema failure mentioning one property as deterministic: renaming that property is the only spec-side fix
- Keep generated .proto files in review so an unexpected rename that shifts hashes is visible
When it happens
Trigger: Running openapi-generator with -g protobuf-schema against a spec that contains a property (or any named field that goes through generateFieldNumberFromString) whose Java String.hashCode mod 536870911 falls in 19000..19999. The failure is deterministic: the same property name always fails, every run.
Common situations: Adding or renaming a property in the OpenAPI spec changes its hash and can suddenly push it into the reserved window (~0.19% chance per field). Teams with large specs hit it eventually; it also appears when migrating an existing spec to the protobuf-schema generator, and the same spec generates fine for other languages because only this generator hashes names into field numbers.
Related errors
- Empty method name (operationId) not allowed
- recursionLimit must be an integer, e.g. 2000.
- property %s in model %s uses generated Python member name %s
- property %s in model %s cannot use %s as its public Python n
- property %s in model %s has invalid generated Python field n
AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22).
Data as JSON: /api/errors/9f280638ce8fce6b.
Report an issue: GitHub.