apache/iceberg · error · MissingSchemaException

Cannot resolve schema for fingerprint:

Error message

Cannot resolve schema for fingerprint: 

What it means

IcebergDecoder resolves Avro decoders by schema fingerprint that were previously registered via addSchema(). If decode encounters a fingerprint that was never registered and no writeSchema was supplied, it throws this MissingSchemaException. It means the stream references a write schema the decoder doesn't know about.

Source

Thrown at core/src/main/java/org/apache/iceberg/data/avro/IcebergDecoder.java:124

    RawDecoder<D> decoder = RawDecoder.create(readSchema, PlannedDataReader::create, writeSchema);
    decoders.put(fp, decoder);
  }

  private RawDecoder<D> getDecoder(long fp) {
    RawDecoder<D> decoder = decoders.get(fp);
    if (decoder != null) {
      return decoder;
    }

    if (resolver != null) {
      Schema writeSchema = resolver.findByFingerprint(fp);
      if (writeSchema != null) {
        addSchema(writeSchema);
        return decoders.get(fp);
      }
    }

    throw new MissingSchemaException("Cannot resolve schema for fingerprint: " + fp);
  }

  @Override
  public D decode(InputStream stream, D reuse) throws IOException {
    byte[] header = HEADER_BUFFER.get();
    try {
      if (!readFully(stream, header)) {
        throw new BadHeaderException("Not enough header bytes");
      }
    } catch (IOException e) {
      throw new IOException("Failed to read header and fingerprint bytes", e);
    }

    if (IcebergEncoder.V1_HEADER[0] != header[0] || IcebergEncoder.V1_HEADER[1] != header[1]) {
      throw new BadHeaderException(
          String.format(
              Locale.ROOT, "Unrecognized header bytes: 0x%02X 0x%02X", header[0], header[1]));
    }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Pass the writer's Avro Schema as writeSchema when constructing IcebergDecoder so unknown fingerprints resolve.
  2. Call addSchema(writerSchema) for every schema that may have produced the streams.
  3. Ensure both producer and consumer register the same schema version; align schema evolution between writer and reader.

Example fix

// before
IcebergDecoder<Record> decoder = new IcebergDecoder<>(reader, null);
decoder.decode(stream, null); // MissingSchemaException for unknown fingerprint
// after
IcebergDecoder<Record> decoder = new IcebergDecoder<>(reader, writeSchema);
decoder.decode(stream, null);
Defensive patterns

Strategy: fallback

Validate before calling

// ensure every producer schema is registered before decoding
for (Schema s : knownWriteSchemas) { decoder.addSchema(s); }

Type guard

null

Try / catch

try { return decoder.decode(stream, reuse); } catch (MissingSchemaException e) { decoder.addSchema(resolveSchemaFromCatalog(e.getMessage())); return decoder.decode(stream, reuse); }

Prevention

When it happens

Trigger: Decoding a stream produced with a schema whose 8-byte fingerprint is absent from the decoder's registry and constructed without a writeSchema fallback (new IcebergDecoder(reader, null) then decode(stream, reuse)).

Common situations: Reading data written by a different process/version with an evolved schema; forgetting to call addSchema for the writer's schema; constructing the decoder without the write schema argument.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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