apache/iceberg · error · UnsupportedOperationException

Avro does not support AAD prefix

Error message

Avro does not support AAD prefix

What it means

The Avro format model's ModelWriteBuilder.withAADPrefix is unsupported: Avro files in Iceberg do not support additional authenticated data (AAD) prefixes used by Parquet modular encryption. Calling this builder method always throws UnsupportedOperationException.

Solutions

  1. Remove the withAADPrefix call when targeting Avro files
  2. Switch the write path to Parquet if AAD-prefix encryption is required
  3. Branch on file format before applying encryption-related builder options

Example fix

// before
writeBuilder(io, location)
    .withAADPrefix(aadPrefix)
    .build(); // avro: throws

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

Strategy: validation

Validate before calling

if ("avro".equals(format) && aadPrefix != null) { throw new IllegalArgumentException("AAD prefix requires Parquet"); }

Type guard

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

Try / catch

try { builder.withAADPrefix(prefix); } catch (UnsupportedOperationException e) { /* strip encryption options for avro */ }

Prevention

When it happens

Trigger: Calling withAADPrefix(bytes) on a write builder obtained from the Avro FormatModel, typically when encryption settings are applied uniformly regardless of the underlying file format.

Common situations: Shared write paths applying Parquet-style encryption parameters to all formats; table write properties enabling AAD prefixes while the writer is Avro; test harnesses exercising encryption flags across format models.

Related errors


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

Appendix: source

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

    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(
              avroSchema -> writerFunction.write(schema, avroSchema, engineSchema));
          break;
        case POSITION_DELETES:
          Preconditions.checkState(
              schema == null,

View on GitHub (pinned to 86d9c8fc54)