apache/pulsar · error · UnsupportedOperationException

Cannot convert from to . Requested converter does not…

Error message

Cannot convert from  to . Requested converter does not exist.

What it means

FieldParser.convert() only supports a fixed set of source->target conversions (String<->Integer/Long/Double/Float/Boolean, direct casts, and String->enum). If the source object's type and target type do not match any registered converter, it throws UnsupportedOperationException. It exists to fail fast instead of silently returning a wrong-typed value during reflective config-field population.

Solutions

  1. Change the field type (or the source value) to one of the supported types: String, Integer, Long, Double, Float, Boolean, enum, or collections thereof.
  2. If the source is a String but the target is unsupported, pre-convert the value yourself before calling convert/update.
  3. Add a public static converter method with the signature Target converter(Source) to a helper class if you control the code, or extend FieldParser with a new converter method pair (e.g. stringToLocalDate).
  4. Check the exception message: it names the exact source and target class names that have no converter registered.

Example fix

// before
Duration d = FieldParser.convert("5000", Duration.class); // UnsupportedOperationException
// after
long millis = FieldParser.convert("5000", Long.class);
Duration d = Duration.ofMillis(millis);
Defensive patterns

Strategy: validation

Validate before calling

private static final Set<Class<?>> SUPPORTED = Set.of(String.class, Integer.class, Long.class, Double.class, Float.class, Boolean.class);
static <T> void checkConvertible(Object from, Class<T> to) {
    if (from != null && !to.isAssignableFrom(from.getClass())
            && !SUPPORTED.contains(from.getClass()) && !to.isEnum()) {
        throw new IllegalArgumentException("no FieldParser converter for "
                + from.getClass().getName() + " -> " + to.getName());
    }
}

Type guard

static boolean isSimpleConvertibleType(Class<?> c) {
    return String.class.equals(c) || Number.class.isAssignableFrom(c)
            || Boolean.class.equals(c) || (c.isEnum() && c.getSuperclass() != null && c.getSuperclass().isEnum());
}

Try / catch

try {
    T v = FieldParser.convert(from, to);
} catch (UnsupportedOperationException e) {
    // no registered converter for this type pair — handle/prefill manually
    log.warn("unsupported conversion", e);
}

Prevention

When it happens

Trigger: Calling FieldParser.convert(obj, Target.class) where obj's runtime class has no registered converter, e.g. convert(42L, Integer.class), convert("abc", LocalDate.class), or a List<String> field whose element type is a non-String/number type reached via stringToList/stringToSet/stringToMap.

Common situations: Populating a Pulsar config object (FieldParser.update) from a properties map where a field is of an unsupported type (Instant, custom POJO, Map with non-primitive values); passing a non-String source to convert(); typos in generic type parameters on config fields.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/a9f102406ed54a9e. Report an issue: GitHub.

Appendix: source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/FieldParser.java:119

            // Converting string to enum
            DeserializationConfig deserializationConfig =
                    ObjectMapperFactory.getMapper().getObjectMapper().getDeserializationConfig();
            // No replacement API available in Jackson 2.x
            AnnotatedClass annotatedEnum = AnnotatedClassResolver.resolve(
                    deserializationConfig,
                    deserializationConfig.getTypeFactory().constructType(to),
                    deserializationConfig
            );
            EnumResolver r = EnumResolver.constructUsingToString(deserializationConfig, annotatedEnum);
            T value = (T) r.findEnum((String) from);
            if (value == null) {
                throw new RuntimeException("Invalid value '" + from + "' for enum " + to);
            }
            return value;
        }

        if (converter == null) {
            throw new UnsupportedOperationException("Cannot convert from " + from.getClass().getName() + " to "
                    + to.getName() + ". Requested converter does not exist.");
        }

        // Convert the value.
        try {
            Object val = converter.invoke(to, from);
            return to.cast(val);
        } catch (Exception e) {
            throw new RuntimeException("Cannot convert from " + from.getClass().getName() + " to " + to.getName()
                    + ". Conversion failed with " + e.getMessage(), e);
        }
    }

    /**
     * Update given Object attribute by reading it from provided map properties.
     *
     * @param properties
     *            which key-value pair of properties to assign those values to given object

View on GitHub (pinned to 820761864e)