{"record":{"id":"5305a18f0927df0a","repo":"apache/iceberg","slug":"failed-to-read-the-version-byte","errorCode":null,"errorMessage":"Failed to read the version byte","messagePattern":"Failed to read the version byte","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/encryption/KeyMetadataDecoder.java","lineNumber":52,"sourceCode":"\n  /**\n   * Creates a new decoder that constructs key metadata instances described by schema version.\n   *\n   * <p>The {@code readSchemaVersion} is as used the version of the expected (read) schema. Datum\n   * instances created by this class will are described by the expected schema.\n   */\n  KeyMetadataDecoder(byte readSchemaVersion) {\n    this.readSchema = StandardKeyMetadata.supportedSchemaVersions().get(readSchemaVersion);\n  }\n\n  @Override\n  public StandardKeyMetadata decode(InputStream stream, StandardKeyMetadata reuse) {\n    byte writeSchemaVersion;\n\n    try {\n      writeSchemaVersion = (byte) stream.read();\n    } catch (IOException e) {\n      throw new UncheckedIOException(\"Failed to read the version byte\", e);\n    }\n\n    if (writeSchemaVersion < 0) {\n      throw new RuntimeException(\"Version byte - end of stream reached\");\n    }\n\n    Schema writeSchema = StandardKeyMetadata.supportedAvroSchemaVersions().get(writeSchemaVersion);\n\n    if (writeSchema == null) {\n      throw new UnsupportedOperationException(\n          \"Cannot resolve schema for version: \" + writeSchemaVersion);\n    }\n\n    RawDecoder<StandardKeyMetadata> decoder = decoders.get(writeSchemaVersion);\n\n    if (decoder == null) {\n      decoder = RawDecoder.create(readSchema, GenericAvroReader::create, writeSchema);\n","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/encryption/KeyMetadataDecoder.java#L34-L70","documentation":"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.","triggerScenarios":"Calling decode(InputStream, ...) where the underlying stream throws an IOException while reading the first byte (IO error, closed/corrupt stream source).","commonSituations":"Reading encrypted-table key metadata from a corrupted or prematurely failing input source; passing a stream backed by a failed IO channel.","solutions":["Check and fix the underlying IO source (file, network) that threw the IOException","Retry reading the key metadata after confirming the source is intact","Inspect the chained cause (getCause) for the root IO failure"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// ensure stream is readable: stream.available() > 0 where applicable","typeGuard":null,"tryCatchPattern":"try { return decoder.decode(stream, null); }\ncatch (UncheckedIOException e) { throw new IOException(\"Key metadata read failed\", e.getCause()); }","preventionTips":["Validate the IO source (file/network) health before reading key metadata","Close and reopen streams rather than reusing failed ones","Always inspect getCause() of UncheckedIOException for the root failure"],"tags":["encryption","io","deserialization"],"backgroundTag":"file-read-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}