apache/hadoop · error · IOException

Can't store credential " + alias + " in " + this

Error message

Can't store credential " + alias + " in " + this

What it means

Thrown by innerSetCredential() when KeyStore.setKeyEntry() rejects the new SecretKeySpec(AES) entry with KeyStoreException. The keystore instance cannot protect/store this kind of key - classically because the store is effectively not a JCEKS store capable of holding secret keys, or its state was not properly initialized for writes.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/AbstractJavaKeyStoreProvider.java:274

        }
      } catch (KeyStoreException e) {
        throw new IOException("Problem removing " + name + " from " + this, e);
      }
      changed = true;
    } finally {
      writeLock.unlock();
    }
  }

  CredentialEntry innerSetCredential(String alias, char[] material)
      throws IOException {
    writeLock.lock();
    try {
      keyStore.setKeyEntry(alias,
          new SecretKeySpec(new String(material).getBytes(StandardCharsets.UTF_8),
              getAlgorithm()), password, null);
    } catch (KeyStoreException e) {
      throw new IOException("Can't store credential " + alias + " in " + this,
          e);
    } finally {
      writeLock.unlock();
    }
    changed = true;
    return new CredentialEntry(alias, material);
  }

  @Override
  public void flush() throws IOException {
    writeLock.lock();
    try {
      if (!changed) {
        LOG.debug("Keystore hasn't changed, returning.");
        return;
      }
      LOG.debug("Writing out keystore.");
      try (OutputStream out = getOutputStreamForKeystore()) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Let Hadoop create the store itself: run 'hadoop credential create <alias> -provider jceks://file/<path>' on a clean path so the file is born as JCEKS
  2. If the file came from keytool, re-create it with -storetype jceks, or export/import the secrets into a fresh Hadoop-managed store
  3. Check javax keystore.type/provider overrides in java.security and the JVM's provider list; remove FIPS restrictions or add a provider that supports JCEKS key protection

Example fix

# before
keytool -genkeypair -keystore /etc/hadoop/creds.jceks   # writes JKS-format store
hadoop credential create s3.key -provider jceks://file/etc/hadoop/creds.jceks   # fails: Can't store credential

# after
rm /etc/hadoop/creds.jceks
hadoop credential create s3.key -provider jceks://file/etc/hadoop/creds.jceks   # Hadoop creates a true JCEKS store
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: the existing file must be a loadable JCEKS before writing entries
static boolean isHealthyJceks(Path file, char[] pw) throws Exception {
  if (!file.toFile().exists() || file.toFile().length() == 0) return true; // will be created fresh
  KeyStore ks = KeyStore.getInstance("jceks");
  try (InputStream in = Files.newInputStream(file)) {
    ks.load(in, pw);
    return true;
  } catch (Exception e) {
    return false;
  }
}

Try / catch

try {
  provider.createCredentialEntry(alias, material);
  provider.flush();
} catch (IOException ex) {
  if (ex.getCause() instanceof java.security.KeyStoreException) {
    // store type cannot hold secret keys or is uninitialized:
    // recreate the file via hadoop credential on a clean path, then retry
  } else { throw ex; }
}

Prevention

When it happens

Trigger: Writing a credential into a store whose bytes are a JKS (or other type) file that was loaded under the jceks provider path; a .jceks-suffixed file actually created by keytool's default store type; keystore instance left uninitialized after a failed load; JVM provider set that cannot protect AES keys.

Common situations: Admin pre-created the file with 'keytool -genkeypair -keystore creds.jceks' (JKS content); mixing keystore tooling between keytool and hadoop credential; FIPS JVMs that disallow the JCEKS key-protection algorithm.

Related errors


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