apache/skywalking · critical · UnexpectedException

Create {stream.builder().getSimpleName()} record DAO failure

Error message

Create {stream.builder().getSimpleName()} record DAO failure.

What it means

RecordStreamProcessor.create() reflectively constructs the StorageBuilder for a @Stream Record class (trace segments, alarms, logs...) and obtains an IRecordDAO from the storage plugin. Any reflective instantiation failure is wrapped in this UnexpectedException, which names the failing builder class and aborts startup.

Source

Thrown at oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/RecordStreamProcessor.java:91

        }
        RecordPersistentWorker worker = workers.get(record.getClass());
        if (worker != null) {
            worker.in(record);
        }
    }

    public void create(ModuleDefineHolder moduleDefineHolder, Stream stream, Class<? extends Record> recordClass) throws StorageException {
        final StorageBuilderFactory storageBuilderFactory = moduleDefineHolder.find(StorageModule.NAME)
                                                                              .provider()
                                                                              .getService(StorageBuilderFactory.class);
        final Class<? extends StorageBuilder> builder = storageBuilderFactory.builderOf(recordClass, stream.builder());

        StorageDAO storageDAO = moduleDefineHolder.find(StorageModule.NAME).provider().getService(StorageDAO.class);
        IRecordDAO recordDAO;
        try {
            recordDAO = storageDAO.newRecordDao(builder.getDeclaredConstructor().newInstance());
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            throw new UnexpectedException("Create " + stream.builder().getSimpleName() + " record DAO failure.", e);
        }

        ModelRegistry modelSetter = moduleDefineHolder.find(CoreModule.NAME).provider().getService(ModelRegistry.class);
        // Record stream doesn't read data from database during the persistent process. Keep the timeRelativeID == false always.
        Model model = modelSetter.add(
            recordClass, stream.scopeId(),
            new Storage(stream.name(), false, DownSampling.Second),
            StorageManipulationOpt.schemaCreateIfAbsent());
        ExportRecordWorker exportWorker = new ExportRecordWorker(moduleDefineHolder);
        RecordPersistentWorker persistentWorker = new RecordPersistentWorker(moduleDefineHolder, model, recordDAO, exportWorker);

        workers.put(recordClass, persistentWorker);
    }
}

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Decode the cause (NoSuchMethodException/InstantiationException/InvocationTargetException) and fix the builder class accordingly — usually add `public Builder() {}`
  2. Confirm the @Stream(builder=...) value names a public concrete StorageBuilder implementation
  3. Rebuild everything with 'mvnw clean install' and remove old plugin jars from the deployed oap-libs directory

Example fix

// before
public static class RecordBuilder implements StorageBuilder {
    public RecordBuilder(String config) {}
}
// after
public static class RecordBuilder implements StorageBuilder {
    public RecordBuilder() {}
}
Defensive patterns

Strategy: try-catch

Validate before calling

// assert the builder is reflectively constructible before packaging
assertNotNull(MyRecord.Builder.class.getDeclaredConstructor());
assertFalse(Modifier.isAbstract(MyRecord.Builder.class.getModifiers()));

Try / catch

Startup failure — do not catch in production; catch UnexpectedException in plugin integration tests and assert on the underlying reflection cause.

Prevention

When it happens

Trigger: A custom Record class's builder lacks a public no-arg constructor or is abstract; the builder constructor throws; a third-party storage plugin jar built against a different OAP API cannot be instantiated.

Common situations: Adding custom record types via plugins; storage plugin version drift after a partial OAP upgrade; fat-jar shading or Java module restrictions blocking reflective access.

Related errors


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/8e734126c82f3440. Report an issue: GitHub.