apache/druid · error · IllegalArgumentException
start metadata cannot be null
Error message
start metadata cannot be null
What it means
commitMetadataOnly() atomically moves a supervisor's metadata from a start value to an end value. It validates all arguments up front and throws IllegalArgumentException when startMetadata is null, because the transactional compare-and-set needs a concrete starting metadata value to match against.
Source
Thrown at server/src/main/java/org/apache/druid/metadata/IndexerSQLMetadataStorageCoordinator.java:617
);
}
@Override
public SegmentPublishResult commitMetadataOnly(
String supervisorId,
String dataSource,
DataSourceMetadata startMetadata,
DataSourceMetadata endMetadata
)
{
if (supervisorId == null) {
throw new IllegalArgumentException("supervisorId cannot be null");
}
if (dataSource == null) {
throw new IllegalArgumentException("datasource name cannot be null");
}
if (startMetadata == null) {
throw new IllegalArgumentException("start metadata cannot be null");
}
if (endMetadata == null) {
throw new IllegalArgumentException("end metadata cannot be null");
}
try {
return inReadWriteDatasourceTransaction(
dataSource,
transaction -> updateDataSourceMetadataInTransaction(
transaction,
supervisorId,
dataSource,
startMetadata,
endMetadata
)
);
}
catch (CallbackFailedException e) {View on GitHub (pinned to 9b90983fd2)
Solutions
- Fetch the current metadata first and only call commitMetadataOnly when it is non-null (create it if missing via the appropriate insert path).
- Handle the 'no metadata yet' case in the caller rather than forwarding null.
- Verify the supervisor id/datasource actually exist in the metadata store before committing.
Example fix
// before
coordinator.commitMetadataOnly(dataSource, id, currentMeta, newMeta); // currentMeta may be null
// after
if (currentMeta != null) {
coordinator.commitMetadataOnly(dataSource, id, currentMeta, newMeta);
} else {
insertInitialMetadata(dataSource, id, newMeta);
} Defensive patterns
Strategy: validation
Validate before calling
if (startMetadata == null) {
// metadata not yet created; handle before committing
throw new IllegalStateException("No existing supervisor metadata to move from");
} Type guard
boolean hasStartMetadata(Metadata m) { return m != null; } Try / catch
try {
coordinator.commitMetadataOnly(dataSource, id, startMeta, endMeta);
} catch (IllegalArgumentException e) {
log.error(e, "Cannot commit supervisor metadata: %s", e.getMessage());
// create metadata row or re-fetch current state
} Prevention
- Always read current metadata via the coordinator before attempting a move
- Treat null reads as 'not initialized' and initialize instead of committing
- Handle concurrent supervisor deletions with re-reads
When it happens
Trigger: Calling commitMetadataOnly with a null startMetadata — e.g. reading the current metadata, getting null (supervisor metadata absent in the store), and passing it straight back in.
Common situations: A supervisor checkpoints before its metadata row was ever created; concurrent delete of supervisor metadata between read and commit; test harness supplying null metadata placeholders.
Related errors
- datasource name cannot be null
- end metadata cannot be null
- supervisorId cannot be null
- Must have a valid, non-null aggregator name
- Must have a valid, non-null aggregator name
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/cc5ed6983df866c8.
Report an issue: GitHub.