{"record":{"id":"820b973adb7b832a","repo":"apache/hadoop","slug":"from-option-s-s-820b97","errorCode":null,"errorMessage":"From option %s %s","messagePattern":"From option (.+?) (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/DefaultOBSClientFactory.java","lineNumber":234,"sourceCode":"   * @param conf    Hadoop configuration\n   * @param obsConf ObsConfiguration\n   * @param name    URL\n   * @return ObsClient client\n   * @throws IOException on any failure to create Huawei OBS client\n   */\n  private static ObsClient createHuaweiObsClient(final Configuration conf,\n      final ObsConfiguration obsConf, final URI name)\n      throws IOException {\n    Class<?> credentialsProviderClass;\n    BasicSessionCredential credentialsProvider;\n    ObsClient obsClient;\n\n    try {\n      credentialsProviderClass = conf.getClass(\n          OBSConstants.OBS_CREDENTIALS_PROVIDER, null);\n    } catch (RuntimeException e) {\n      Throwable c = e.getCause() != null ? e.getCause() : e;\n      throw new IOException(\n          \"From option \" + OBSConstants.OBS_CREDENTIALS_PROVIDER + ' '\n              + c, c);\n    }\n\n    if (credentialsProviderClass == null) {\n      return createObsClientWithoutCredentialsProvider(conf, obsConf,\n          name);\n    }\n\n    try {\n      Constructor<?> cons =\n          credentialsProviderClass.getDeclaredConstructor(URI.class,\n              Configuration.class);\n      credentialsProvider = (BasicSessionCredential) cons.newInstance(\n          name, conf);\n    } catch (NoSuchMethodException\n        | SecurityException\n        | IllegalAccessException","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/DefaultOBSClientFactory.java#L216-L252","documentation":"While creating the ObsClient, DefaultOBSClientFactory does conf.getClass(\"fs.obs.credentials.provider\", null). If looking up that option throws a RuntimeException (classically ClassNotFoundException/RuntimeException from RunJar for a misspelled or missing class), it is wrapped in IOException('From option fs.obs.credentials.provider <cause>') with the cause preserved. The message therefore names the config key and embeds the underlying reason — read the tail of the message for the real class-loading error.","triggerScenarios":"fs.obs.credentials.provider points to a class not on the classpath (typo, wrong FQCN, jar missing from lib/ or the executor classpath); the value names an interface/abstract class; a shaded/relocated jar renamed the class between connector versions; the class exists but static initializers throw.","commonSituations":"Upgrading hadoop-huaweicloud where provider classes moved packages; deploying an OBS connector build that does not bundle the custom provider used in an older cluster; Spark executors missing the jar that is present on the driver; class name copy-pasted with spaces or from documentation of a different fork.","solutions":["Read the appended cause: 'class ... not found' means classpath, anything else (e.g. InstantiationException from abstract class) means the class itself.","Fix the FQCN in fs.obs.credentials.provider (e.g. com.obs.services.EnvironmentVariableObsCredentialsProvider or org.apache.hadoop.fs.obs.OBSCredentialsProvider*) and verify with a tiny program doing Class.forName(name).","Ship the provider jar to every node/executor (Spark: --jars or ship into hadoop lib dir), then restart.","If you did not intend a custom provider, delete the option — a null value falls back to createObsClientWithoutCredentialsProvider (static AK/SK from config)."],"exampleFix":"# before\n<property><name>fs.obs.credentials.provider</name>\n  <value>com.obs.MyCredentialsProivder</value></property> <!-- typo -->\n\n# after\n<property><name>fs.obs.credentials.provider</name>\n  <value>com.obs.MyCredentialsProvider</value></property>\n<!-- verify: java -cp ... Class.forName check, or spark-shell --jars provider.jar -->","handlingStrategy":"validation","validationCode":"static boolean providerClassLoads(String fqcn) {\n  try { Class.forName(fqcn, false, Thread.currentThread().getContextClassLoader()); return true; }\n  catch (Throwable t) { return false; }\n}\nString cls = conf.get(\"fs.obs.credentials.provider\");\nif (cls != null && !providerClassLoads(cls)) throw new ConfigException(\"missing provider class \" + cls);","typeGuard":null,"tryCatchPattern":"try {\n  FileSystem.get(obsUri, conf);\n} catch (IOException e) {\n  if (String.valueOf(e.getMessage()).startsWith(\"From option fs.obs.credentials.provider\")) {\n    throw new ConfigException(\"fs.obs.credentials.provider misconfigured: \" + e.getMessage(), e);\n  }\n  throw e;\n}","preventionTips":["Smoke-test Class.forName on the exact classpath the job uses (driver AND executors).","Pin provider class names in one shared config module, not copy-pasted per job.","After connector upgrades, grep release notes for provider package renames."],"tags":["obs","huaweicloud","credentials","class-loading","config"],"backgroundTag":"invalid-config-class","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}