apache/hadoop · error · IOException

Must specify a key name when creating an encryption zone

Error message

Must specify a key name when creating an encryption zone

What it means

ensureKeyIsInitialized rejects a null or empty keyName with IOException before it ever contacts the key provider: an encryption zone must be bound to a named key so the NameNode can later generate EDEKs for files in the zone. This is purely argument validation after the provider check — the key itself need not exist yet at this line (a missing key fails later with 'Key ... doesn't exist').

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirEncryptionZoneOp.java:122

              throw new IOException(e);
            }
          }
        });
    long generateEDEKTime = monotonicNow() - generateEDEKStartTime;
    NameNode.getNameNodeMetrics().addGenerateEDEKTime(generateEDEKTime);
    Preconditions.checkNotNull(edek);
    return edek;
  }

  static KeyProvider.Metadata ensureKeyIsInitialized(final FSDirectory fsd,
      final String keyName, final String src) throws IOException {
    KeyProviderCryptoExtension provider = fsd.getProvider();
    if (provider == null) {
      throw new IOException("Can't create an encryption zone for " + src
          + " since no key provider is available.");
    }
    if (keyName == null || keyName.isEmpty()) {
      throw new IOException("Must specify a key name when creating an "
          + "encryption zone");
    }
    EncryptionFaultInjector.getInstance().ensureKeyIsInitialized();
    KeyProvider.Metadata metadata = provider.getMetadata(keyName);
    if (metadata == null) {
      /*
       * It would be nice if we threw something more specific than
       * IOException when the key is not found, but the KeyProvider API
       * doesn't provide for that. If that API is ever changed to throw
       * something more specific (e.g. UnknownKeyException) then we can
       * update this to match it, or better yet, just rethrow the
       * KeyProvider's exception.
       */
      throw new IOException("Key " + keyName + " doesn't exist.");
    }
    // If the provider supports pool for EDEKs, this will fill in the pool
    provider.warmUpEncryptedKeys(keyName);
    return metadata;

View on GitHub (pinned to 2add963021)

Solutions

  1. Supply a non-empty key name: 'hdfs crypto -createZone -key mykey -path /secure'.
  2. Validate the keyName argument in your provisioning code (Preconditions.checkNotNull + isNotEmpty) before calling HdfsAdmin.
  3. Fail fast in deploy scripts when the key-name variable is unset instead of passing it through.

Example fix

# before
hdfs crypto -createZone -path /secure  # no -key

# after
hdfs crypto -createZone -key mykey -path /secure
Defensive patterns

Strategy: validation

Validate before calling

if (keyName == null || keyName.trim().isEmpty()) {
  throw new IllegalArgumentException("Encryption zone requires a non-empty key name");
}
admin.createEncryptionZone(path, keyName);

Try / catch

catch (IOException e) {
  if (e.getMessage() != null && e.getMessage().contains("Must specify a key name")) {
    throw new IllegalArgumentException("Fix provisioning config: key name was empty", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: HdfsAdmin.createEncryptionZone(path, null) or with an empty string; shell wrapper scripts calling 'hdfs crypto -createZone -path <p>' without -key; code that reads the key name from config/environment and passes it through unvalidated.

Common situations: Automation templates with an unset ${KEY_NAME} variable that expands to empty; config-driven provisioning where the key property was renamed but the code still reads the old name; interactive scripts where the -key flag is optional but zone creation is not.

Related errors


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