{"record":{"id":"8c38d08c6cf20d1b","repo":"apache/beam","slug":"builder-method-has-to-be-explicitly-allowed","errorCode":null,"errorMessage":"Builder method  has to be explicitly allowed","messagePattern":"Builder method  has to be explicitly allowed","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java","lineNumber":182,"sourceCode":"                + \" with parameter schema \"\n                + builderMethod.getSchema(),\n            e);\n      }\n    }\n\n    return transform;\n  }\n\n  private boolean isBuilderMethodForName(\n      Method method, String nameFromPayload, AllowedClass allowListClass) {\n    // Lookup based on method annotations\n    for (Annotation annotation : method.getAnnotations()) {\n      if (annotation instanceof MultiLanguageBuilderMethod) {\n        if (nameFromPayload.equals(((MultiLanguageBuilderMethod) annotation).name())) {\n          if (allowListClass.isAllowedBuilderMethod(nameFromPayload)) {\n            return true;\n          } else {\n            throw new RuntimeException(\n                \"Builder method \" + nameFromPayload + \" has to be explicitly allowed\");\n          }\n        }\n      }\n    }\n\n    // Lookup based on the method name.\n    boolean match = method.getName().equals(nameFromPayload);\n    String consideredMethodName = method.getName();\n\n    // We provide a simplification for common Java builder pattern naming convention where builder\n    // methods start with \"with\". In this case, for a builder method name in the form \"withXyz\",\n    // users may just use \"xyz\". If additional updates to the method name are needed the transform\n    // has to be updated by adding annotations.\n    if (!match && consideredMethodName.length() > 4 && consideredMethodName.startsWith(\"with\")) {\n      consideredMethodName =\n          consideredMethodName.substring(4, 5).toLowerCase() + consideredMethodName.substring(5);\n      match = consideredMethodName.equals(nameFromPayload);","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java#L164-L200","documentation":"The builder method matched by its @MultiLanguageBuilderMethod name, but that method is not on the expansion service's allowlist, so the service refuses to invoke it. The allowlist (isAllowedBuilderMethod) is a security control preventing arbitrary code execution through the expansion service.","triggerScenarios":"Requesting expansion of a transform whose payload names a @MultiLanguageBuilderMethod-annotated method that was not explicitly added to the configured allowlist of the expansion service.","commonSituations":"Using XLang (e.g. Python/Go calling a Java transform) without registering the builder method in the expansion service's allowed builder methods configuration; adding new builder methods to a transform but forgetting to update the allowlist.","solutions":["Add the builder method name to the expansion service's allowed-builder-methods allowlist configuration and restart the service.","If you control the transform, use the standard annotated-constructor/builder registration expected by the service so it is allowlisted.","Check the allowlist configuration file/format (allowed class/method list) for typos in the method name."],"exampleFix":"// before: expansion service started without allowlist entry\njava -jar expansion.jar\n// after\njava -jar expansion.jar --allowedBuilderMethods=com.example.MyTransform:withCount","handlingStrategy":"validation","validationCode":"ExpansionServiceConfig cfg = service.getConfig();\nif (!cfg.getAllowedBuilderMethods(transformClass).contains(annotatedMethodName)) {\n  throw new IllegalStateException(\"Builder method must be allowlisted: \" + annotatedMethodName);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return getTransform(payload);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"has to be explicitly allowed\")) {\n    throw new SecurityException(\"Builder method not allowlisted on expansion service: \" + payload.getName(), e);\n  }\n  throw e;\n}","preventionTips":["Maintain the allowlist as code/config reviewed alongside the transform.","Document the allowed builder methods for operators of the expansion service.","Add a CI check that every @MultiLanguageBuilderMethod is present in the service allowlist.","Prefer allowing specific methods over broad class-level grants."],"tags":["java","security","allowlist","beam-expansion-service"],"backgroundTag":"permission-denied","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}