This is an automated email from the ASF dual-hosted git repository.

chia7712 pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/kafka.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 8b7cf2bc6f5 KAFKA-20129 Fix server error when appending or subtracting 
a non-existent config key (#21425)
8b7cf2bc6f5 is described below

commit 8b7cf2bc6f524e8888080a12391916e4ac63344a
Author: Lan Ding <[email protected]>
AuthorDate: Tue Feb 10 03:38:50 2026 +0800

    KAFKA-20129 Fix server error when appending or subtracting a non-existent 
config key (#21425)
    
    Replace `configKeys(configName)` with `configKeys.get(configName)`
    pattern matching  to throw `InvalidConfigurationException` instead of
    `NoSuchElementException` for  non-existent config keys in
    APPEND/SUBTRACT operations.
    
    Reviewers: Chia-Ping Tsai <[email protected]>
---
 .../scala/kafka/server/ConfigAdminManager.scala    | 10 +++++----
 .../unit/kafka/server/ConfigAdminManagerTest.scala | 24 +++++++++++++++++++++-
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/core/src/main/scala/kafka/server/ConfigAdminManager.scala 
b/core/src/main/scala/kafka/server/ConfigAdminManager.scala
index 7394d2cfc43..f86af7d37af 100644
--- a/core/src/main/scala/kafka/server/ConfigAdminManager.scala
+++ b/core/src/main/scala/kafka/server/ConfigAdminManager.scala
@@ -417,10 +417,12 @@ object ConfigAdminManager {
     configKeys: Map[String, ConfigKey]
   ): Unit = {
     def listType(configName: String, configKeys: Map[String, ConfigKey]): 
Boolean = {
-      val configKey = configKeys(configName)
-      if (configKey == null)
-        throw new InvalidConfigurationException(s"Unknown config name: 
$configName")
-      configKey.`type` == ConfigDef.Type.LIST
+      configKeys.get(configName) match {
+        case Some(configKey) =>
+          configKey.`type` == ConfigDef.Type.LIST
+        case None =>
+          throw new InvalidConfigurationException(s"Unknown config name: 
$configName")
+      }
     }
 
     alterConfigOps.foreach { alterConfigOp =>
diff --git a/core/src/test/scala/unit/kafka/server/ConfigAdminManagerTest.scala 
b/core/src/test/scala/unit/kafka/server/ConfigAdminManagerTest.scala
index 6d865219322..5e4ae95ee13 100644
--- a/core/src/test/scala/unit/kafka/server/ConfigAdminManagerTest.scala
+++ b/core/src/test/scala/unit/kafka/server/ConfigAdminManagerTest.scala
@@ -23,7 +23,9 @@ import java.util.Collections
 import kafka.utils.TestUtils
 import org.apache.kafka.clients.admin.AlterConfigOp.OpType
 import org.apache.kafka.common.config.ConfigResource.Type.{BROKER, 
BROKER_LOGGER, TOPIC, UNKNOWN}
-import org.apache.kafka.common.errors.InvalidRequestException
+import org.apache.kafka.clients.admin.{AlterConfigOp, ConfigEntry}
+import org.apache.kafka.common.config.ConfigDef.ConfigKey
+import org.apache.kafka.common.errors.{InvalidConfigurationException, 
InvalidRequestException}
 import org.apache.kafka.common.message.{AlterConfigsRequestData, 
AlterConfigsResponseData, IncrementalAlterConfigsRequestData, 
IncrementalAlterConfigsResponseData}
 import 
org.apache.kafka.common.message.AlterConfigsRequestData.{AlterConfigsResource 
=> LAlterConfigsResource}
 import 
org.apache.kafka.common.message.AlterConfigsRequestData.{AlterConfigsResourceCollection
 => LAlterConfigsResourceCollection}
@@ -419,4 +421,24 @@ class ConfigAdminManagerTest {
     assertFalse(ConfigAdminManager.containsDuplicates(Seq("foo", "bar", 
"baz")))
     assertTrue(ConfigAdminManager.containsDuplicates(Seq("foo", "bar", "baz", 
"foo")))
   }
+
+  @Test
+  def testPrepareIncrementalConfigsWithNonExistentKey(): Unit = {
+    val configProps = new java.util.Properties()
+    val configKeys: Map[String, ConfigKey] = Map.empty
+
+    val appendOp = new AlterConfigOp(
+      new ConfigEntry("non.existent.key", "value"), OpType.APPEND)
+    assertEquals("Unknown config name: non.existent.key",
+      Assertions.assertThrows(classOf[InvalidConfigurationException],
+        () => ConfigAdminManager.prepareIncrementalConfigs(
+          Seq(appendOp), configProps, configKeys)).getMessage)
+
+    val subtractOp = new AlterConfigOp(
+      new ConfigEntry("non.existent.key", "value"), OpType.SUBTRACT)
+    assertEquals("Unknown config name: non.existent.key",
+      Assertions.assertThrows(classOf[InvalidConfigurationException],
+        () => ConfigAdminManager.prepareIncrementalConfigs(
+          Seq(subtractOp), configProps, configKeys)).getMessage)
+  }
 }
\ No newline at end of file

Reply via email to