apache/skywalking · critical · UnexpectedException
Create {stream.getBuilder().getSimpleName()} metrics DAO fai
Error message
Create {stream.getBuilder().getSimpleName()} metrics DAO failure. What it means
MetricsStreamProcessor.create() reflectively builds the StorageBuilder for a metrics class and obtains an IMetricsDAO from the configured storage plugin. Wrapped reflection failures (missing/throwing/inaccessible no-arg builder constructor, abstract builder) are rethrown as this UnexpectedException, aborting OAP startup for that stream.
Source
Thrown at oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsStreamProcessor.java:219
private void create(ModuleDefineHolder moduleDefineHolder,
StreamDefinition stream,
Class<? extends Metrics> metricsClass,
MetricStreamKind kind,
StorageManipulationOpt opt) throws StorageException {
final StorageBuilderFactory storageBuilderFactory = moduleDefineHolder.find(StorageModule.NAME)
.provider()
.getService(StorageBuilderFactory.class);
final Class<? extends StorageBuilder> builder = storageBuilderFactory.builderOf(
metricsClass, stream.getBuilder());
StorageDAO storageDAO = moduleDefineHolder.find(StorageModule.NAME).provider().getService(StorageDAO.class);
IMetricsDAO metricsDAO;
try {
metricsDAO = storageDAO.newMetricsDao(builder.getDeclaredConstructor().newInstance());
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException |
InvocationTargetException e) {
throw new UnexpectedException("Create " + stream.getBuilder().getSimpleName() + " metrics DAO failure.", e);
}
ModelRegistry modelSetter = moduleDefineHolder.find(CoreModule.NAME).provider().getService(ModelRegistry.class);
DownSamplingConfigService configService = moduleDefineHolder.find(CoreModule.NAME)
.provider()
.getService(DownSamplingConfigService.class);
TTLStatusQuery ttlStatusQuery = moduleDefineHolder.find(CoreModule.NAME)
.provider()
.getService(TTLStatusQuery.class);
MetricsPersistentWorker hourPersistentWorker = null;
MetricsPersistentWorker dayPersistentWorker = null;
MetricsTransWorker transWorker = null;
final MetricsExtension metricsExtension = metricsClass.getAnnotation(MetricsExtension.class);
/**
* All metrics default are `supportDownSampling` and `insertAndUpdate`, unless it has explicit definition.View on GitHub (pinned to 102af09b4a)
Solutions
- Read the cause exception: NoSuchMethodException -> add public no-arg constructor; InstantiationException -> make builder concrete; InvocationTargetException -> fix the exception thrown inside the builder constructor
- Verify the @Stream annotation's builder class is public, top-level-accessible, and compiled against the current server-core
- Clean and rebuild: 'mvnw clean install' to remove stale jars, and confirm no duplicate plugin versions in the distribution's oap-libs
Example fix
// before
@Stream(name = "my_metric", builder = MyMetric.Builder.class, ...)
public static class Builder { /* only a private constructor */ }
// after
public static class Builder implements StorageBuilder {
public Builder() {}
// storageBuilder0 / entity2Storage implementations
} Defensive patterns
Strategy: try-catch
Validate before calling
// plugin self-check at test time assertNotNull(MyMetric.Builder.class.getDeclaredConstructor()); // must exist and be public assertTrue(StorageBuilder.class.isAssignableFrom(MyMetric.Builder.class));
Try / catch
At startup this must fail fast (do not catch); in integration tests, catch UnexpectedException, unwrap with getCause(), and assert it identifies the exact builder defect (NoSuchMethodException vs InvocationTargetException).
Prevention
- Standardize builder classes: public static, implements StorageBuilder, explicit public no-arg constructor
- Run the OAP boot once in CI for custom plugins — DAO creation errors surface immediately
- Avoid custom builder constructors with required arguments
When it happens
Trigger: A custom Metrics class's @Stream(builder=...) points to a builder without a public no-arg constructor, an abstract class, or a constructor that throws; or a storage plugin jar version mismatch makes instantiation fail.
Common situations: Adding a custom OAL metrics function/plugin and misdeclaring its builder; deploying OAP with mixed-version storage plugin jars in oap-libs; a shaded/fat jar breaking reflective access under a restrictive module path.
Related errors
- Create {stream.builder().getSimpleName()} none stream record
- Create {stream.builder().getSimpleName()} none stream record
- Create {stream.builder().getSimpleName()} record DAO failure
- Create {stream.builder().getSimpleName()} top n record DAO f
- Metric TTL should be at least 2 days, current value is {}
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/bfdbacc685dc1953.
Report an issue: GitHub.