{"record":{"id":"d69859be1f9285bf","repo":"apache/iceberg","slug":"class-s-was-not-found","errorCode":null,"errorMessage":"Class %s was not found","messagePattern":"Class (.+?) was not found","errorType":"exception","errorClass":"BadConfigurationException","httpStatus":null,"severity":"error","filePath":"parquet/src/main/java/org/apache/iceberg/parquet/ParquetCodecFactory.java","lineNumber":67,"sourceCode":"    String cacheKey = cacheKey(codecName);\n    CompressionCodec codec = CODEC_BY_NAME.get(cacheKey);\n    if (codec != null) {\n      return codec;\n    }\n\n    try {\n      Class<?> codecClass;\n      try {\n        codecClass = Class.forName(codecClassName);\n      } catch (ClassNotFoundException e) {\n        // Try to load the class using the job classloader\n        codecClass = configuration.getClassLoader().loadClass(codecClassName);\n      }\n      codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, configuration);\n      CODEC_BY_NAME.put(cacheKey, codec);\n      return codec;\n    } catch (ClassNotFoundException e) {\n      throw new BadConfigurationException(\"Class \" + codecClassName + \" was not found\", e);\n    }\n  }\n\n  @SuppressWarnings(\"deprecation\")\n  private String cacheKey(CompressionCodecName codecName) {\n    String level = null;\n    switch (codecName) {\n      case GZIP:\n        level = configuration.get(\"zlib.compress.level\");\n        break;\n      case BROTLI:\n        level = configuration.get(\"compression.brotli.quality\");\n        break;\n      case ZSTD:\n        level = configuration.get(\"parquet.compression.codec.zstd.level\");\n        if (level == null) {\n          // keep \"io.compression.codec.zstd.level\" for backwards compatibility\n          level = configuration.get(\"io.compression.codec.zstd.level\");","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/parquet/src/main/java/org/apache/iceberg/parquet/ParquetCodecFactory.java#L49-L85","documentation":"Thrown when a Parquet compression codec class configured via the codec class-name property cannot be loaded by the configuration's class loader. The factory resolves codec classes reflectively (Hadoop CompressionCodec); if loadClass fails with ClassNotFoundException it wraps it in BadConfigurationException. This indicates the codec class name is wrong or the codec's JAR is not on the classpath.","triggerScenarios":"Calling getCodec with a codec class name string that is misspelled, not a Hadoop CompressionCodec implementation, or whose JAR is absent from the classpath; also when a custom codec plugin was removed or the shaded/deployment JAR excludes it.","commonSituations":"Typo in table property like write.parquet.compression-codec or Hadoop io.compression.codecs; deploying a slim runtime image missing hadoop-codec JARs (e.g. zstd/brotli implementations); switching clusters where custom codecs are not installed.","solutions":["Fix the codec class name to a fully-qualified existing CompressionCodec class (e.g. org.apache.hadoop.io.compress.ZstdCodec).","Add the JAR containing the codec to the runtime classpath of the job/driver and executors.","Fall back to a built-in codec (snappy, gzip, zstd) that ships with the distribution.","Verify the class is visible to the configuration's classLoader (check fat-jar shading/relocation)."],"exampleFix":"// before\nconf.set(\"write.parquet.compression-codec\", \"zstandard\");\n// after\nconf.set(\"write.parquet.compression-codec\", \"org.apache.hadoop.io.compress.ZstdCodec\");","handlingStrategy":"validation","validationCode":"String cls = conf.get(\"write.parquet.compression-codec\");\nif (cls != null) {\n  try {\n    Class<?> c = Class.forName(cls, true, Thread.currentThread().getContextClassLoader());\n    if (!org.apache.hadoop.io.compress.CompressionCodec.class.isAssignableFrom(c)) {\n      throw new IllegalArgumentException(cls + \" is not a CompressionCodec\");\n    }\n  } catch (ClassNotFoundException e) {\n    throw new IllegalArgumentException(\"Codec class not on classpath: \" + cls, e);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  codec = ParquetCodecFactory.getCodec(conf, name, level);\n} catch (BadConfigurationException e) {\n  LOG.warn(\"Codec unavailable, falling back to SNAPPY\", e);\n  codec = ParquetCodecFactory.getCodec(conf, \"snappy\", null);\n}","preventionTips":["Use standard codec short names (snappy, gzip, zstd) that Iceberg maps internally instead of raw class names.","Keep codec JARs in the runtime/deployment image, not just the driver classpath.","Test write paths in CI with the exact compression property set."],"tags":["parquet","reflection","configuration","codec","classpath"],"backgroundTag":"class-not-found","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"}