apache/iceberg · error · UnsupportedOperationException

Avro does not support file encryption keys

Error message

Avro does not support file encryption keys

What it means

The Avro format model's ModelWriteBuilder.withFileEncryptionKey is unsupported: Avro file writing in Iceberg does not implement file-level encryption keys (unlike Parquet). Calling this builder method always throws UnsupportedOperationException. To write encrypted files, use a format that supports encryption, such as Parquet.

Source

Thrown at core/src/main/java/org/apache/iceberg/avro/AvroFormatModel.java:151

      this.content = newContent;
      return this;
    }

    @Override
    public ModelWriteBuilder<D, S> metricsConfig(MetricsConfig metricsConfig) {
      internal.metricsConfig(metricsConfig);
      return this;
    }

    @Override
    public ModelWriteBuilder<D, S> overwrite() {
      internal.overwrite();
      return this;
    }

    @Override
    public ModelWriteBuilder<D, S> withFileEncryptionKey(ByteBuffer encryptionKey) {
      throw new UnsupportedOperationException("Avro does not support file encryption keys");
    }

    @Override
    public ModelWriteBuilder<D, S> withAADPrefix(ByteBuffer aadPrefix) {
      throw new UnsupportedOperationException("Avro does not support AAD prefix");
    }

    @Override
    public FileAppender<D> build() throws IOException {
      switch (content) {
        case DATA:
          internal.createContextFunc(Avro.WriteBuilder.Context::dataContext);
          internal.createWriterFunc(
              avroSchema -> writerFunction.write(schema, avroSchema, engineSchema));
          break;
        case EQUALITY_DELETES:
          internal.createContextFunc(Avro.WriteBuilder.Context::deleteContext);
          internal.createWriterFunc(

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Use Parquet (or ORC with format-appropriate support) when file encryption keys are required
  2. Remove the withFileEncryptionKey call when writing Avro files
  3. Gate encryption configuration on the actual file format before calling the builder
  4. Store encryption at a different layer (e.g. storage-side encryption) instead of Avro file-level keys

Example fix

// before
FormatModel model = table.formatModel("avro");
model.writeBuilder(io, location).withFileEncryptionKey(key).build();

// after
if ("parquet".equals(format)) {
  model.writeBuilder(io, location).withFileEncryptionKey(key).build();
} else {
  model.writeBuilder(io, location).build();
}
Defensive patterns

Strategy: validation

Validate before calling

if ("avro".equals(format) && encryptionKey != null) { throw new IllegalArgumentException("Avro does not support file encryption keys"); }

Type guard

boolean supportsEncryptionKeys(FormatModel m) { return !(m instanceof AvroFormatModel); }

Try / catch

try { builder.withFileEncryptionKey(key); } catch (UnsupportedOperationException e) { /* fall back to unencrypted or Parquet */ }

Prevention

When it happens

Trigger: Calling writeBuilder(table.io(), table.location()).withFileEncryptionKey(key) with content type set to Avro, e.g. while configuring table properties for encryption and then writing Avro manifests/data files through the generic FormatModel API.

Common situations: Configuring encryption generically across formats and hitting the Avro path; code that assumes all formats support write encryption keys; migrating Parquet writes to Avro without removing encryption settings.

Related errors


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