prestodb/presto · error

NOT_FOUND

NOT_FOUND

Error message

Failed to factory serializer class.  Is it on the classpath?

What it means

AccumuloRecordSet's constructor reflectively instantiates the AccumuloRowSerializer class named in the split configuration via Class.getConstructor().newInstance(). Any reflective failure (class missing, instantiation error, no no-arg constructor) is wrapped as NOT_FOUND with this message. It almost always means the serializer class is not on the Presto classpath or cannot be constructed.

Source

Thrown at presto-accumulo/src/main/java/com/facebook/presto/accumulo/io/AccumuloRecordSet.java:82

            Connector connector,
            ConnectorSession session,
            AccumuloSplit split,
            String username,
            List<AccumuloColumnHandle> columnHandles)
    {
        requireNonNull(session, "session is null");
        requireNonNull(split, "split is null");
        requireNonNull(username, "username is null");
        constraints = requireNonNull(split.getConstraints(), "constraints is null");

        rowIdName = split.getRowId();

        // Factory the serializer based on the split configuration
        try {
            this.serializer = split.getSerializerClass().getConstructor().newInstance();
        }
        catch (Exception e) {
            throw new PrestoException(NOT_FOUND, "Failed to factory serializer class.  Is it on the classpath?", e);
        }

        // Save off the column handles and create a list of the Accumulo types
        this.columnHandles = requireNonNull(columnHandles, "column handles is null");
        ImmutableList.Builder<Type> types = ImmutableList.builder();
        for (AccumuloColumnHandle column : columnHandles) {
            types.add(column.getType());
        }
        this.columnTypes = types.build();

        try {
            // Create the BatchScanner and set the ranges from the split
            scanner = connector.createBatchScanner(split.getFullTableName(), getScanAuthorizations(session, split, connector, username), 10);
            scanner.setRanges(split.getRanges());
        }
        catch (Exception e) {
            throw new PrestoException(UNEXPECTED_ACCUMULO_ERROR, format("Failed to create batch scanner for table %s", split.getFullTableName()), e);
        }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Deploy the JAR containing the serializer class to the presto-accumulo plugin directory on every node and restart Presto
  2. Verify the fully-qualified serializer class name stored in the table metadata is correct
  3. Ensure the class is public with a public no-arg constructor (implement AccumuloRowSerializer)
  4. Check worker logs for the wrapped cause to distinguish ClassNotFound vs instantiation failures

Example fix

// before
public class MySerializer {
    MySerializer() {}
}
// after
public class MySerializer extends AccumuloRowSerializer {
    public MySerializer() {}
}
Defensive patterns

Strategy: validation

Validate before calling

String cls = split.getSerializerClass().getName();
try {
    Class.forName(cls);
} catch (ClassNotFoundException e) {
    throw new IllegalStateException("Serializer class not on classpath: " + cls);
}

Type guard

boolean isInstantiableSerializer(String name) {
    try {
        Class<?> c = Class.forName(name);
        return AccumuloRowSerializer.class.isAssignableFrom(c)
            && java.lang.reflect.Modifier.isPublic(c.getModifiers())
            && Arrays.stream(c.getConstructors()).anyMatch(ctor -> ctor.getParameterCount() == 0);
    } catch (ClassNotFoundException e) { return false; }
}

Try / catch

try {
    // query / create record set
} catch (PrestoException e) {
    if (e.getErrorCode().getName().equals("NOT_FOUND") && e.getMessage().contains("Failed to factory serializer")) {
        // redeploy serializer JAR to plugin dir, fix class name, retry
    }
    throw e;
}

Prevention

When it happens

Trigger: Creating an AccumuloRecordSet for a split whose getSerializerClass() names a class absent from the classpath, an abstract class, a class without a public no-arg constructor, or whose constructor throws.

Common situations: Custom serializer plugin JAR not deployed to the coordinator/workers' plugin directory; class name typo in table metadata; serializer class compiled against a different Presto/connector version and failing to initialize; non-public default constructor.

Understand the failure class

Background: NOT_FOUND error code: why tRPC, Harbor, Nacos and other libraries return 404 "not found" errors for resources that may still exist — this error's family across 11 libraries.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/669b077455636109. Report an issue: GitHub.