apache/iceberg · error · RuntimeException

Failed to create GCM cipher

Error message

Failed to create GCM cipher

What it means

Ciphers.newCipher requests a Cipher instance for 'AES/GCM/NoPadding' and wraps any GeneralSecurityException (NoSuchAlgorithmException, NoSuchPaddingException) in a RuntimeException. This is a static failure of the JVM's crypto environment, not of user input.

Solutions

  1. Run on a standard JDK 8+ where SunJCE provides AES/GCM/NoPadding
  2. Inspect java.security configuration and registered security.providers
  3. Re-add or fix the missing JCE provider; check the chained cause
Defensive patterns

Strategy: try-catch

Validate before calling

static boolean gcmAvailable() {
  try { javax.crypto.Cipher.getInstance("AES/GCM/NoPadding"); return true; }
  catch (GeneralSecurityException e) { return false; }
}

Try / catch

try {
  useEncryption();
} catch (RuntimeException e) {
  if ("Failed to create GCM cipher".equals(e.getMessage())) {
    throw new EnvironmentException("JVM lacks AES/GCM provider; check java.security and providers", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: First use of any Ciphers encrypt/decrypt path on a JVM that has no provider implementing AES/GCM/NoPadding, or where provider initialization throws.

Common situations: Highly restricted/custom JVMs or exotic runtimes (some stripped-down embedded JREs) without AES-GCM; broken java.security configuration; a custom Provider list that removed the SunJCE.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/da601bb6887297ad. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/encryption/Ciphers.java:202

      return plaintextLength;
    }
  }

  private static SecretKeySpec newKey(byte[] keyBytes) {
    Preconditions.checkArgument(keyBytes != null, "Invalid key: null");
    int keyLength = keyBytes.length;
    Preconditions.checkArgument(
        (keyLength == 16 || keyLength == 24 || keyLength == 32),
        "Invalid key length: %s (must be 16, 24, or 32 bytes)",
        keyLength);
    return new SecretKeySpec(keyBytes, "AES");
  }

  private static Cipher newCipher() {
    try {
      return Cipher.getInstance("AES/GCM/NoPadding");
    } catch (GeneralSecurityException e) {
      throw new RuntimeException("Failed to create GCM cipher", e);
    }
  }

  static byte[] streamBlockAAD(byte[] fileAadPrefix, int currentBlockIndex) {
    byte[] blockAAD =
        ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(currentBlockIndex).array();

    if (null == fileAadPrefix) {
      return blockAAD;
    } else {
      byte[] aad = new byte[fileAadPrefix.length + 4];
      System.arraycopy(fileAadPrefix, 0, aad, 0, fileAadPrefix.length);
      System.arraycopy(blockAAD, 0, aad, fileAadPrefix.length, 4);
      return aad;
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)