apache/iceberg · error · UncheckedIOException

Failed to read the version byte

Error message

Failed to read the version byte

What it means

KeyMetadataDecoder.decode wraps IOException from reading the first (version) byte of the key metadata stream in an UncheckedIOException. It indicates the underlying stream failed during reading, not that the data was wrong.

Source

Thrown at core/src/main/java/org/apache/iceberg/encryption/KeyMetadataDecoder.java:52

  /**
   * Creates a new decoder that constructs key metadata instances described by schema version.
   *
   * <p>The {@code readSchemaVersion} is as used the version of the expected (read) schema. Datum
   * instances created by this class will are described by the expected schema.
   */
  KeyMetadataDecoder(byte readSchemaVersion) {
    this.readSchema = StandardKeyMetadata.supportedSchemaVersions().get(readSchemaVersion);
  }

  @Override
  public StandardKeyMetadata decode(InputStream stream, StandardKeyMetadata reuse) {
    byte writeSchemaVersion;

    try {
      writeSchemaVersion = (byte) stream.read();
    } catch (IOException e) {
      throw new UncheckedIOException("Failed to read the version byte", e);
    }

    if (writeSchemaVersion < 0) {
      throw new RuntimeException("Version byte - end of stream reached");
    }

    Schema writeSchema = StandardKeyMetadata.supportedAvroSchemaVersions().get(writeSchemaVersion);

    if (writeSchema == null) {
      throw new UnsupportedOperationException(
          "Cannot resolve schema for version: " + writeSchemaVersion);
    }

    RawDecoder<StandardKeyMetadata> decoder = decoders.get(writeSchemaVersion);

    if (decoder == null) {
      decoder = RawDecoder.create(readSchema, GenericAvroReader::create, writeSchema);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check and fix the underlying IO source (file, network) that threw the IOException
  2. Retry reading the key metadata after confirming the source is intact
  3. Inspect the chained cause (getCause) for the root IO failure
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure stream is readable: stream.available() > 0 where applicable

Try / catch

try { return decoder.decode(stream, null); }
catch (UncheckedIOException e) { throw new IOException("Key metadata read failed", e.getCause()); }

Prevention

When it happens

Trigger: Calling decode(InputStream, ...) where the underlying stream throws an IOException while reading the first byte (IO error, closed/corrupt stream source).

Common situations: Reading encrypted-table key metadata from a corrupted or prematurely failing input source; passing a stream backed by a failed IO channel.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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