{"record":{"id":"30c37af09b8a0461","repo":"apache/beam","slug":"unable-to-register-extensions-for-s","errorCode":null,"errorMessage":"Unable to register extensions for %s","messagePattern":"Unable to register extensions for (.+?)","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/ProtoCoder.java","lineNumber":145,"sourceCode":"    return of(protoMessageClass);\n  }\n\n  /**\n   * Validate that all extensionHosts are able to be registered.\n   *\n   * @param moreExtensionHosts\n   */\n  void validateExtensions(Iterable<Class<?>> moreExtensionHosts) {\n    for (Class<?> extensionHost : moreExtensionHosts) {\n      // Attempt to access the required method, to make sure it's present.\n      try {\n        Method registerAllExtensions =\n            extensionHost.getDeclaredMethod(\"registerAllExtensions\", ExtensionRegistry.class);\n        checkArgument(\n            Modifier.isStatic(registerAllExtensions.getModifiers()),\n            \"Method registerAllExtensions() must be static\");\n      } catch (NoSuchMethodException | SecurityException e) {\n        throw new IllegalArgumentException(\n            String.format(\"Unable to register extensions for %s\", extensionHost.getCanonicalName()),\n            e);\n      }\n    }\n  }\n\n  /**\n   * Returns a {@link ProtoCoder} like this one, but with the extensions from the given classes\n   * registered.\n   *\n   * <p>Each of the extension host classes must be an class automatically generated by the Protocol\n   * Buffers compiler, {@code protoc}, that contains messages.\n   *\n   * <p>Does not modify this object.\n   */\n  public ProtoCoder<T> withExtensionsFrom(Iterable<Class<?>> moreExtensionHosts) {\n    validateExtensions(moreExtensionHosts);\n    return new ProtoCoder<>(","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/ProtoCoder.java#L127-L163","documentation":"Thrown by ProtoCoder.validateExtensions when the given extensionHost class does not expose a usable static registerAllExtensions(ExtensionRegistry) method. Protobuf-generated outer classes provide this method to register extension fields; if it is missing or inaccessible, extensions cannot be registered for the coder.","triggerScenarios":"Calling ProtoCoder.withExtensionsFrom(SomeClass) where SomeClass is not a protobuf-generated outer class, or is a generated class from a protobuf version/toolchain that does not emit registerAllExtensions, or where a SecurityManager blocks reflective access to the method.","commonSituations":"Passing a Message inner class instead of the generated outer class holding the extensions; mixing protobuf runtime versions so the generated code shape differs; proguard/minification stripping the static method.","solutions":["Pass the protobuf-generated outer (container) class, not an individual message class.","Regenerate the proto with protoc --java_out so registerAllExtensions is generated.","Check that the protobuf runtime version matches the protoc version used for codegen.","If minified, add a keep rule for registerAllExtensions."],"exampleFix":"// before\nProtoCoder.of(MyOuter.Message.class).withExtensionsFrom(MyOuter.Message.class);\n// after\nProtoCoder.of(MyOuter.Message.class).withExtensionsFrom(MyOuter.class);","handlingStrategy":"validation","validationCode":"try {\n  Method m = extHost.getDeclaredMethod(\"registerAllExtensions\", ExtensionRegistry.class);\n  if (!Modifier.isStatic(m.getModifiers())) throw new IllegalArgumentException(\"not static\");\n} catch (NoSuchMethodException e) {\n  throw new IllegalArgumentException(extHost + \" is not a protobuf outer class\");\n}","typeGuard":null,"tryCatchPattern":"try { coder.withExtensionsFrom(host); } catch (IllegalArgumentException e) { log.error(\"bad extension host: {}\", e.getMessage()); }","preventionTips":["Pass the generated outer class, never inner message classes.","Keep protoc and protobuf-java runtime versions aligned.","Add proguard keep rules for generated registerAllExtensions."],"tags":["java","protobuf","reflection"],"backgroundTag":"invalid-argument-value","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"}