apache/beam · error · java.lang.RuntimeException
Builder method name has to be explicitly allowed
Error message
Builder method name has to be explicitly allowed
What it means
A builder method matched the requested name (either directly or by the withX -> x field-name convention), but the method is not on the service's allowlist. This is the allowlist security check failing for the conventional 'withX'/field-name matching path, distinct from the @MultiLanguageBuilderMethod path.
Solutions
- Allowlist the resolved method name (the lower-cased field name form shown in the message) in the expansion service configuration.
- Rename your payload to use the exact builder method name and ensure that name is allowlisted.
- Confirm with the service operator which builder methods are permitted before building the pipeline payload.
Example fix
// before
payload: {name: "count"} // withCount not allowlisted
// after: operator adds 'count' (or 'withCount') to allowed builder methods for the transform, then retry Defensive patterns
Strategy: validation
Validate before calling
String resolved = fieldName.startsWith("with")
? Character.toLowerCase(fieldName.charAt(4)) + fieldName.substring(5) : fieldName;
if (!allowList.isAllowedBuilderMethod(resolved)) {
throw new IllegalStateException("Allowlist the field-name form '" + resolved + "' before expanding");
} Try / catch
try {
return getMethod(transform, row, allowList);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("has to be explicitly allowed")) {
throw new SecurityException("Method name not allowlisted: " + e.getMessage(), e);
}
throw e;
} Prevention
- When allowlisting withX methods, allowlist both the exact name and the derived field name if clients use field names.
- Publish the effective allowlist to cross-language pipeline authors.
- Version the allowlist with the transform artifact.
- Add integration tests that attempt expansion of each permitted method.
When it happens
Trigger: Expansion payload names a builder method via field-name convention (e.g. 'count' matching withCount) that exists on the transform but is not in the expansion service's allowed builder methods list.
Common situations: Cross-language users referencing Java transform builder methods by field name without the service operator having allowlisted them; allowlist updated for the exact method name but not the lower-cased field-name variant expected here.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Builder method has to be explicitly allowed
- Constructor method needs to be explicitly allowed
- cannot register Coder : method named 'of' with arguments…
- Cannot unzip file containing an entry with ".." in the…
- Could not determine a schema for type
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/82ebdaa66124b70f.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java:203
}
}
}
// Lookup based on the method name.
boolean match = method.getName().equals(nameFromPayload);
String consideredMethodName = method.getName();
// We provide a simplification for common Java builder pattern naming convention where builder
// methods start with "with". In this case, for a builder method name in the form "withXyz",
// users may just use "xyz". If additional updates to the method name are needed the transform
// has to be updated by adding annotations.
if (!match && consideredMethodName.length() > 4 && consideredMethodName.startsWith("with")) {
consideredMethodName =
consideredMethodName.substring(4, 5).toLowerCase() + consideredMethodName.substring(5);
match = consideredMethodName.equals(nameFromPayload);
}
if (match && !allowListClass.isAllowedBuilderMethod(consideredMethodName)) {
throw new RuntimeException(
"Builder method name " + consideredMethodName + " has to be explicitly allowed");
}
return match;
}
private Method getMethod(
PTransform<PInput, POutput> transform,
BuilderMethod builderMethod,
AllowedClass allowListClass) {
Row builderMethodRow = decodeRow(builderMethod.getSchema(), builderMethod.getPayload());
List<Method> matchingMethods =
Arrays.stream(transform.getClass().getMethods())
.filter(m -> isBuilderMethodForName(m, builderMethod.getName(), allowListClass))
.filter(m -> parametersCompatible(m.getParameters(), builderMethodRow))
.filter(m -> PTransform.class.isAssignableFrom(m.getReturnType()))
.collect(Collectors.toList());View on GitHub (pinned to 12126d8942)