apache/hadoop · error · IOException

Cannot find serializer for {}

Error message

Cannot find serializer for {}

What it means

This is the catch branch around NativeSerialization.getInstance().getSerializer(keyCls): the lookup itself threw an IOException (serializer factory failed while constructing the serializer, not a plain null return). init re-throws it as a new IOException whose message only names the key class - the original exception is not chained, so the root detail is visible only in surrounding logs, if at all.

Source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src/main/java/org/apache/hadoop/mapred/nativetask/NativeMapOutputCollectorDelegator.java:127

    final Class<?> keyCls = job.getMapOutputKeyClass();
    try {
      @SuppressWarnings("rawtypes")
      final INativeSerializer serializer = NativeSerialization.getInstance().getSerializer(keyCls);
      if (null == serializer) {
        String message = "Key type not supported. Cannot find serializer for " + keyCls.getName();
        LOG.error(message);
        throw new InvalidJobConfException(message);
      } else if (!Platforms.support(keyCls.getName(), serializer, job)) {
        String message = "Native output collector doesn't support this key, " +
          "this key is not comparable in native: " + keyCls.getName();
        LOG.error(message);
        throw new InvalidJobConfException(message);
      }
    } catch (final IOException e) {
      String message = "Cannot find serializer for " + keyCls.getName();
      LOG.error(message);
      throw new IOException(message);
    }

    final boolean ret = NativeRuntime.isNativeLibraryLoaded();
    if (ret) {
      if (job.getBoolean(MRJobConfig.MAP_OUTPUT_COMPRESS, false)) {
        String codec = job.get(MRJobConfig.MAP_OUTPUT_COMPRESS_CODEC);
        if (!NativeRuntime.supportsCompressionCodec(codec.getBytes(StandardCharsets.UTF_8))) {
          String message = "Native output collector doesn't support compression codec " + codec;
          LOG.error(message);
          throw new InvalidJobConfException(message);
        }
      }
      NativeRuntime.configure(job);

      final long updateInterval = job.getLong(Constants.NATIVE_STATUS_UPDATE_INTERVAL,
          Constants.NATIVE_STATUS_UPDATE_INTERVAL_DEFVAL);
      updater = new StatusReportChecker(context.getReporter(), updateInterval);
      updater.start();

View on GitHub (pinned to 2add963021)

Solutions

  1. Check the task log for the original IOException thrown by the serializer factory - this message does not carry the cause
  2. Verify the serializer factory class for the key type loads cleanly on the task classpath (dependencies present, no linkage errors)
  3. Fall back to a standard supported key type or disable the native collector (unset mapreduce.job.map.output.collector.class) until the factory is fixed
Defensive patterns

Strategy: try-catch

Try / catch

try {
  collector.init(context);
} catch (IOException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Cannot find serializer for")) {
    // outer wrapper: inspect earlier task-log lines for the factory's original IOException
    LOG.error("native serializer factory failed for " + keyCls.getName());
  }
  throw e;
}

Prevention

When it happens

Trigger: A registered serializer factory for the map output key class throws during instantiation (missing dependency, broken platform init, unexpected reflection error) while the native output collector initializes.

Common situations: Custom INativeSerializer factories that fail construction (classpath issues, native calls before library config); platform JARs present but their transitive dependencies missing on task classpaths.

Related errors


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