apache/hadoop · error · UnsupportedOperationException

%s doesn't support getObjectTagging.

Error message

%s doesn't support getObjectTagging.

What it means

ObjectStorage.getTags has a default implementation that throws UnsupportedOperationException("<ClassName> doesn't support getObjectTagging."). Only the real TOS backend overrides it (TOS.getTags), so reading tags from the local FileStore backend or a custom implementation without an override fails with this error.

Source

Thrown at hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/object/ObjectStorage.java:336

   *
   * @param key     the key of the object key.
   * @param newTags the new tags to put.
   * @throws RuntimeException if key doesn't exist.
   */
  default void putTags(String key, Map<String, String> newTags) {
    throw new UnsupportedOperationException(
        this.getClass().getSimpleName() + " doesn't support putObjectTagging.");
  }

  /**
   * Get all attached tags of the object.
   *
   * @param key the key of the object.
   * @return map containing all tags.
   * @throws RuntimeException if key doesn't exist.
   */
  default Map<String, String> getTags(String key) {
    throw new UnsupportedOperationException(
        this.getClass().getSimpleName() + " doesn't support getObjectTagging.");
  }

  /**
   * Gets the object status for the given key.
   * It's different from {@link ObjectStorage#head(String)}, it returns object info if the key
   * exists or the prefix with value key exists.
   * <p>
   * There are three kinds of implementations:
   * <ul>
   *   <li>Uses the headObject API if the object storage support directory bucket and the requested
   *   bucket is a directory bucket, the object storage will return object directly if the file or
   *   dir exists, otherwise return null</li>
   *   <li>Uses getFileStatus API if the object storage support it, e.g. TOS. The object storage
   *   will return the object directly if the key or prefix exists, otherwise return null.</li>
   *   <li>If the object storage doesn't support above all cases, you have to try to headObject(key)
   *   at first, if the object doesn't exist, and then headObject(key + "/") later if the key
   *   doesn't end with '/', and if neither the new key doesn't exist, and then use listObjects API

View on GitHub (pinned to 2add963021)

Solutions

  1. Use the real TOS object storage when tag reads are required
  2. Guard with a capability check (instanceof TOS or a supportsTags flag) before calling getTags
  3. Override getTags in custom ObjectStorage implementations where the backend supports it
  4. Degrade gracefully: skip tagging features when unsupported instead of failing

Example fix

// before
Map<String, String> tags = storage.getTags(key);

// after
Map<String, String> tags = (storage instanceof TOS)
    ? storage.getTags(key)
    : Collections.emptyMap();
Defensive patterns

Strategy: type-guard

Type guard

private static boolean supportsTagging(ObjectStorage storage) {
  return storage instanceof org.apache.hadoop.fs.tosfs.object.tos.TOS;
}

Try / catch

try {
  Map<String, String> tags = storage.getTags(key);
} catch (UnsupportedOperationException e) {
  // backend without tagging support: degrade to empty tags
  return Collections.emptyMap();
}

Prevention

When it happens

Trigger: Calling ObjectStorage.getTags(key) on a FileStore instance or a custom ObjectStorage plugin that did not override the default method, typically while porting tag-reading logic from the TOS backend to another backend.

Common situations: Tests running against the file-based backend; custom storage plugins that never implement tagging; code assuming every ObjectStorage supports object tagging.

Related errors


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