{"record":{"id":"27d68c2e8d87a8eb","repo":"apache/hadoop","slug":"codec-not-configured-for-custom-codec","errorCode":null,"errorMessage":"Codec not configured for custom codec {}","messagePattern":"Codec not configured for custom codec (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/erasurecode/CodecUtil.java","lineNumber":280,"sourceCode":"    case ErasureCodeConstants.RS_LEGACY_CODEC_NAME:\n      //TODO:rs-legacy should be handled differently.\n      return conf.get(\n          CodecUtil.IO_ERASURECODE_CODEC_RS_KEY,\n          CodecUtil.IO_ERASURECODE_CODEC_RS);\n    case ErasureCodeConstants.XOR_CODEC_NAME:\n      return conf.get(\n          CodecUtil.IO_ERASURECODE_CODEC_XOR_KEY,\n          CodecUtil.IO_ERASURECODE_CODEC_XOR);\n    case ErasureCodeConstants.HHXOR_CODEC_NAME:\n      return conf.get(\n          CodecUtil.IO_ERASURECODE_CODEC_HHXOR_KEY,\n          CodecUtil.IO_ERASURECODE_CODEC_HHXOR);\n    default:\n      // For custom codec, we throw exception if the factory is not configured\n      String codecKey = \"io.erasurecode.codec.\" + codec + \".coder\";\n      String codecClass = conf.get(codecKey);\n      if (codecClass == null) {\n        throw new IllegalArgumentException(\"Codec not configured \" +\n                \"for custom codec \" + codec);\n      }\n      return codecClass;\n    }\n  }\n}\n","sourceCodeStart":262,"sourceCodeEnd":287,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/erasurecode/CodecUtil.java#L262-L287","documentation":"Thrown by CodecUtil.getCodecClassName (reached via CodecUtil.createEncoder / createDecoder) when the schema's codec name is not one of the built-in cases in the switch (\"rs\", \"rs-legacy\", \"xor\", \"hhxor\"). For any other name Hadoop falls into the custom-codec path, which requires the Configuration key \"io.erasurecode.codec.<codec>.coder\" to be set to a class name; the class is later loaded and must be a subclass of org.apache.hadoop.io.erasurecode.codec.ErasureCodec with a (Configuration, ErasureCodecOptions) constructor. A missing key means the codec name is unrecognized and unconfigured, so an IllegalArgumentException is thrown before any coding happens.","triggerScenarios":"Calling CodecUtil.createEncoder(conf, options) or CodecUtil.createDecoder(conf, options) where options.getSchema().getCodecName() is a custom or misspelled name (e.g. \"RS\", \"rs \", \"mycodec\") while conf has no \"io.erasurecode.codec.<name>.coder\" entry. In HDFS this happens when a user-defined EC policy schema is applied but the codec class property was never added to the NameNode/DataNode configuration.","commonSituations":"Deploying a site-specific ErasureCodec on only some nodes; typo or wrong case in the codec name of an EC policy schema; policy files copied between clusters whose configuration does not define the custom coder key; Hadoop upgrades where codec naming conventions changed.","solutions":["If a standard codec was intended, change the schema's codec name to exactly \"rs\", \"rs-legacy\", \"xor\", or \"hhxor\" (case-sensitive, no surrounding whitespace)","For a genuinely custom codec, set conf property \"io.erasurecode.codec.<codec>.coder\" to the canonical class name of your ErasureCodec implementation on every process that builds coders (NameNode for policy handling, DataNodes for actual EC work)","Verify the effective configuration in the failing process with conf.get(\"io.erasurecode.codec.<name>.coder\") and confirm the class is on the classpath","Ensure the configured class extends ErasureCodec and exposes a public (Configuration, ErasureCodecOptions) constructor"],"exampleFix":"// before\nConfiguration conf = new Configuration();\n// schema uses codec name \"mycodec\" but nothing is configured\nErasureEncoder enc = CodecUtil.createEncoder(conf, options); // IllegalArgumentException\n\n// after\nconf.set(\"io.erasurecode.codec.mycodec.coder\",\n    \"com.example.codec.MyErasureCodec\"); // class extends ErasureCodec\nErasureEncoder enc = CodecUtil.createEncoder(conf, options);","handlingStrategy":"validation","validationCode":"String codec = schema.getCodecName();\nboolean builtin = codec.equals(\"rs\") || codec.equals(\"rs-legacy\")\n    || codec.equals(\"xor\") || codec.equals(\"hhxor\");\nif (!builtin && conf.get(\"io.erasurecode.codec.\" + codec + \".coder\") == null) {\n  throw new IllegalStateException(\"Custom codec '\" + codec\n      + \"' has no io.erasurecode.codec.\" + codec + \".coder property\");\n}\nErasureEncoder enc = CodecUtil.createEncoder(conf, options);","typeGuard":null,"tryCatchPattern":"try {\n  encoder = CodecUtil.createEncoder(conf, options);\n} catch (IllegalArgumentException e) {\n  // message names the codec; surface a config hint to operators\n  throw new ConfigurationException(\"EC codec '\" + codecName\n      + \"' not configured: set io.erasurecode.codec.\" + codecName + \".coder\", e);\n}","preventionTips":["Validate codec names and their .coder properties in a startup self-check for every process that performs EC work","Keep custom codec names in one constants class shared by policy authors and config authors","Assert codec creation succeeds in unit tests for every EC policy you deploy"],"tags":["erasure-coding","hadoop-common","configuration","illegalargumentexception"],"backgroundTag":"missing-config-key","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}