apache/hadoop · error · IOException

Invalid cipher suite, %s=%s

Error message

Invalid cipher suite, %s=%s

What it means

When negotiating a crypto cipher for encrypted data transfer, DataTransferSaslUtil.negotiateCipherOption accepts exactly 'aes/ctr/nopadding' or 'sm4/ctr/nopadding' as the value of dfs.encrypt.data.transfer.cipher.suites (the key is singular despite the name). Any other value throws IOException before negotiation starts.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/datatransfer/sasl/DataTransferSaslUtil.java:323

  /**
   * Negotiate a cipher option which server supports.
   *
   * @param conf the configuration
   * @param options the cipher options which client supports
   * @return CipherOption negotiated cipher option
   */
  public static CipherOption negotiateCipherOption(Configuration conf,
      List<CipherOption> options) throws IOException {
    // Negotiate cipher suites if configured.  Currently, the only supported
    // cipher suite is AES/CTR/NoPadding or SM4/CTR/NoPadding, but the protocol
    // allows multiple values for future expansion.
    String cipherSuites = conf.get(DFS_ENCRYPT_DATA_TRANSFER_CIPHER_SUITES_KEY);
    if (cipherSuites == null || cipherSuites.isEmpty()) {
      return null;
    }
    if (!cipherSuites.equals(CipherSuite.AES_CTR_NOPADDING.getName()) &&
        !cipherSuites.equals(CipherSuite.SM4_CTR_NOPADDING.getName())) {
      throw new IOException(String.format("Invalid cipher suite, %s=%s",
          DFS_ENCRYPT_DATA_TRANSFER_CIPHER_SUITES_KEY, cipherSuites));
    }
    if (options != null) {
      for (CipherOption option : options) {
        CipherSuite suite = option.getCipherSuite();
        if (suite == CipherSuite.AES_CTR_NOPADDING ||
            suite == CipherSuite.SM4_CTR_NOPADDING) {
          int keyLen = conf.getInt(
              DFS_ENCRYPT_DATA_TRANSFER_CIPHER_KEY_BITLENGTH_KEY,
              DFS_ENCRYPT_DATA_TRANSFER_CIPHER_KEY_BITLENGTH_DEFAULT) / 8;
          CryptoCodec codec = CryptoCodec.getInstance(conf, suite);
          byte[] inKey = new byte[keyLen];
          byte[] inIv = new byte[suite.getAlgorithmBlockSize()];
          byte[] outKey = new byte[keyLen];
          byte[] outIv = new byte[suite.getAlgorithmBlockSize()];
          assert codec != null;
          codec.generateSecureRandom(inKey);
          codec.generateSecureRandom(inIv);

View on GitHub (pinned to 2add963021)

Solutions

  1. Set dfs.encrypt.data.transfer.cipher.suites=aes/ctr/nopadding (or sm4/ctr/nopadding where supported) on all nodes
  2. Unset the property to use SASL privacy without an accelerated crypto cipher
  3. Confirm the CryptoCodec implementation for the chosen suite (native OpenSSL libs) is present on all nodes

Example fix

<!-- before -->
<property>
  <name>dfs.encrypt.data.transfer.cipher.suites</name>
  <value>AES/CTR/PKCS5Padding</value>
</property>

<!-- after -->
<property>
  <name>dfs.encrypt.data.transfer.cipher.suites</name>
  <value>aes/ctr/nopadding</value>
</property>
Defensive patterns

Strategy: validation

Validate before calling

String suite = conf.getTrimmed("dfs.encrypt.data.transfer.cipher.suites", "");
if (!suite.isEmpty()
    && !suite.equals("aes/ctr/nopadding")
    && !suite.equals("sm4/ctr/nopadding")) {
  throw new IllegalArgumentException("Unsupported cipher suite: " + suite);
}

Prevention

When it happens

Trigger: dfs.encrypt.data.transfer enabled with privacy QOP and dfs.encrypt.data.transfer.cipher.suites set to an unsupported string such as 'AES/CTR/PKCS5Padding', '3des', or a typo; thrown as soon as the node/client tries to negotiate cipher options.

Common situations: Copying JCE or OpenSSL cipher names into the property; expecting a comma-separated list of suites; older versions that do not know SM4.

Related errors


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