apache/hadoop · error · IOException

No KeyProviderFactory for ${uri} in ${KEY_PROVIDER_PATH}

Error message

No KeyProviderFactory for ${uri} in ${KEY_PROVIDER_PATH}

What it means

KeyProviderFactory.getProviders parses each entry of hadoop.security.key.provider.path as a URI and asks every KeyProviderFactory registered via ServiceLoader; if none accepts the URI (get(uri, conf) returns null), the entry is unusable and the whole call fails with 'No KeyProviderFactory for <uri>'. The URI scheme determines which factory handles it (jceks, user, kms, ...).

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProviderFactory.java:72

  // Lazy loading would require synchronization in concurrent use cases.
  static {
    Iterator<KeyProviderFactory> iterServices = serviceLoader.iterator();
    while (iterServices.hasNext()) {
      iterServices.next();
    }
  }
  
  public static List<KeyProvider> getProviders(Configuration conf
                                               ) throws IOException {
    List<KeyProvider> result = new ArrayList<KeyProvider>();
    for(String path: conf.getStringCollection(KEY_PROVIDER_PATH)) {
      try {
        URI uri = new URI(path);
        KeyProvider kp = get(uri, conf);
        if (kp != null) {
          result.add(kp);
        } else {
          throw new IOException("No KeyProviderFactory for " + uri + " in " +
              KEY_PROVIDER_PATH);
        }
      } catch (URISyntaxException error) {
        throw new IOException("Bad configuration of " + KEY_PROVIDER_PATH +
            " at " + path, error);
      }
    }
    return result;
  }

  /**
   * Create a KeyProvider based on a provided URI.
   *
   * @param uri key provider URI
   * @param conf configuration to initialize the key provider
   * @return the key provider for the specified URI, or <code>NULL</code> if
   *         a provider for the specified URI scheme could not be found.
   * @throws IOException thrown if the provider failed to initialize.

View on GitHub (pinned to 2add963021)

Solutions

  1. Use a supported scheme in exact form: jceks://file/abs/path, user:///, kms://https://host:9600/kms
  2. Re-check the scheme spelling in hadoop.security.key.provider.path
  3. Ensure the provider implementation jar and its META-INF/services/org.apache.hadoop.crypto.key.KeyProviderFactory file are on the classpath
  4. Isolate the bad entry: test each URI with `hadoop key list -provider <uri>`

Example fix

<!-- before (core-site.xml) -->
<property><name>hadoop.security.key.provider.path</name><value>jkse://file/keys.jceks</value></property>

<!-- after -->
<property><name>hadoop.security.key.provider.path</name><value>jceks://file/keys.jceks</value></property>
Defensive patterns

Strategy: validation

Validate before calling

static final Set<String> SCHEMES = Set.of("jceks", "user", "kms");
for (String entry : conf.getStringCollection("hadoop.security.key.provider.path")) {
  URI u = new URI(entry);
  if (!SCHEMES.contains(u.getScheme())) {
    throw new IllegalArgumentException("unsupported provider scheme: " + entry);
  }
}
List<KeyProvider> providers = KeyProviderFactory.getProviders(conf);

Try / catch

try { providers = KeyProviderFactory.getProviders(conf); } catch (IOException e) { if (String.valueOf(e.getMessage()).startsWith("No KeyProviderFactory")) { // fix scheme/classpath for the named URI, then rebuild config } else { throw e; } }

Prevention

When it happens

Trigger: A scheme typo such as 'jkse://' or 'kms:/host'; a scheme whose implementing jar (e.g. hadoop-kms) is missing from the classpath so its ServiceLoader entry is absent; a raw file path with no scheme that no factory claims.

Common situations: Hand-editing core-site.xml provider paths; mixing up formats between jceks://file/abs/path, user:/// and kms://https://host:9600/kms; shaded/classloader setups that hide META-INF/services entries.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/199dd8db12530c51. Report an issue: GitHub.