apache/hadoop · error · FileNotFoundException

f.toString()

Error message

f.toString()

What it means

TypedBytesWritableInput.readWritable(Writable writable) decodes a typed-bytes WRITABLE (code 50) record: the payload carries the source class name plus its serialized fields. When you pass a non-null reuse object whose class name differs from the name embedded in the payload, it throws IOException 'wrong Writable class given'. Passing null is supported — the reader reflectively instantiates the recorded class via conf.getClassByName.

Source

Thrown at hadoop-cloud-storage-project/hadoop-bos/src/main/java/org/apache/hadoop/fs/bos/BaiduBosFileSystem.java:698

      key = pathToKey(f) + FOLDER_SUFFIX;
    }

    store.storeEmptyFile(key, this.store.getEnvUserName(),
        this.store.getEnvGroupName());
    return true;
  }

  @Override
  public FSDataInputStream open(Path f, int bufferSize)
      throws IOException {
    Path absolutePath = makeAbsolute(f);
    String key = pathToKey(absolutePath);

    FileMetadata fileMetaData = null;
    try {
      fileMetaData = store.retrieveMetadata(key);
    } catch (FileNotFoundException ignore) {
      throw new FileNotFoundException(f.toString());
    }

    if (fileMetaData.isFolder()) {
      throw new FileNotFoundException("Can not open a folder");
    }

    BosInputStream bosFsInputStream = new BosInputStream(
        key, fileMetaData, this.store, this.statistics);

    bosFsInputStream.setReadahead(this.readAhead);
    return new FSDataInputStream(
        new BufferedFSInputStream(
            bosFsInputStream, this.readBufferSize));
  }

  private void createParent(Path path) throws IOException {
    Path parent = path.getParent();
    if (parent != null) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Pass null and let the reader instantiate the correct class per record (costlier but always type-safe).
  2. Or only reuse an object when writable.getClass().getName().equals(expectedName); otherwise allocate fresh.
  3. Keep the Writable class name stable across writer and reader deployments — avoid renaming/moving the class between versions.
  4. Ensure the recorded class is on the reader's classpath when using null reuse, or ClassNotFoundException surfaces as IOException.

Example fix

// before
MyFixedWritable reuse = new MyFixedWritable();
while (nextKeyValues()) {
  reader.readWritable(reuse); // throws when record's class != MyFixedWritable
}

// after
Writable w = reader.readWritable(null); // instantiate from embedded class name
Defensive patterns

Strategy: type-guard

Type guard

static boolean matchesRecordClass(Writable reuse, String embeddedClassName) {
  return reuse == null || reuse.getClass().getName().equals(embeddedClassName);
}

Try / catch

try {
  Writable w = tbIn.readWritable(reuse);
} catch (IOException e) {
  if ("wrong Writable class given".equals(e.getMessage())) {
    w = tbIn.readWritable(null); // retry once, instantiating the embedded class
  } else throw e;
}

Prevention

When it happens

Trigger: Calling readWritable(w) with a reuse object of class X while the stream's next WRITABLE record was written from class Y (e.g. WritableComparator-cached or pooled objects of a fixed type reused across heterogeneous records).

Common situations: Object-reuse optimizations in custom RecordReaders where one Writable instance is recycled for many records; streams where different Writable classes are interleaved; renaming/moving the writer-side Writable class so getName() no longer matches on the reader side.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/17354a21904b3675. Report an issue: GitHub.