{"record":{"id":"779f38fc06ecfb42","repo":"apache/iceberg","slug":"cannot-initialize-kms-client-kmsimpl-does-not","errorCode":null,"errorMessage":"Cannot initialize kms client, ${kmsImpl} does not implement KeyManagementClient interface","messagePattern":"Cannot initialize kms client, (.+?) does not implement KeyManagementClient interface","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/encryption/EncryptionUtil.java","lineNumber":89,"sourceCode":"    DynConstructors.Ctor<KeyManagementClient> ctor;\n    try {\n      ctor =\n          DynConstructors.builder(KeyManagementClient.class)\n              .loader(EncryptionUtil.class.getClassLoader())\n              .impl(kmsImpl)\n              .buildChecked();\n    } catch (NoSuchMethodException e) {\n      throw new IllegalArgumentException(\n          String.format(\n              \"Cannot initialize KeyManagementClient, missing no-arg constructor for class %s\",\n              kmsImpl),\n          e);\n    }\n\n    try {\n      kmsClient = ctor.newInstance();\n    } catch (ClassCastException e) {\n      throw new IllegalArgumentException(\n          String.format(\n              \"Cannot initialize kms client, %s does not implement KeyManagementClient interface\",\n              kmsImpl),\n          e);\n    }\n\n    kmsClient.initialize(catalogProperties);\n\n    return kmsClient;\n  }\n\n  public static EncryptionManager createEncryptionManager(\n      List<EncryptedKey> keys, Map<String, String> tableProperties, KeyManagementClient kmsClient) {\n    Preconditions.checkArgument(kmsClient != null, \"Invalid KMS client: null\");\n    String tableKeyId = tableProperties.get(TableProperties.ENCRYPTION_TABLE_KEY);\n\n    if (null == tableKeyId) {\n      // Unencrypted table","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/encryption/EncryptionUtil.java#L71-L107","documentation":"Thrown by EncryptionUtil.createKmsClient when the class named by the kmsImpl configuration property was instantiated reflectively but does not implement the KeyManagementClient interface. The library requires every custom KMS client to implement this interface so it can be used uniformly for key wrapping/unwrapping. The original ClassCastException is chained as the cause.","triggerScenarios":"Calling EncryptionUtil.createKmsClient (directly or via table encryption configuration) with a kms-impl property pointing to a class that exists and has a no-arg constructor but only implements KmsClient, not KeyManagementClient.","commonSituations":"Configuring an old custom KMS client class written against a previous interface; pointing kms-impl at a helper/wrapper class instead of the actual client; copy-pasting an impl class name from documentation for a different Iceberg version.","solutions":["Make the configured class implement org.apache.iceberg.encryption.KeyManagementClient (or extend a base adapter that does)","Verify the kms-impl property value points to the intended client class, not a wrapper or helper","Check the Iceberg version's docs: older samples may reference classes that predate KeyManagementClient"],"exampleFix":"// before\npublic class MyKmsClient implements KmsClient { ... }\n// after\npublic class MyKmsClient implements KeyManagementClient { ... }","handlingStrategy":"validation","validationCode":"Class<?> clazz = Class.forName(kmsImpl);\nif (!KeyManagementClient.class.isAssignableFrom(clazz)) {\n  throw new IllegalArgumentException(kmsImpl + \" must implement KeyManagementClient\");\n}","typeGuard":"boolean isKmsClient(Object o) { return o instanceof KeyManagementClient; }","tryCatchPattern":"try { kmsClient = EncryptionUtil.createKmsClient(kmsImpl); }\ncatch (IllegalArgumentException e) { log.error(\"Bad kms-impl: {}\", kmsImpl, e); throw e; }","preventionTips":["Confirm the configured class implements KeyManagementClient before deploying","Keep kms-impl values in sync with the Iceberg version's API","Write a startup smoke test that instantiates the configured KMS client"],"tags":["encryption","kms","configuration","reflection"],"backgroundTag":"type-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}