grpc/grpc-java · error · ResourceInvalidException
outlier_detection base_ejection_time is not a valid Duration
Error message
outlier_detection base_ejection_time is not a valid Duration
What it means
validateOutlierDetection throws this ResourceInvalidException when the outlier_detection.base_ejection_time field is present but is not a valid protobuf Duration (Durations.isValid fails, e.g. nanos out of range). The gRPC xDS client rejects the whole Cluster resource because it cannot interpret the ejection duration. The config must be corrected at the management server before the cluster can load.
Source
Thrown at xds/src/main/java/io/grpc/xds/XdsClusterResource.java:386
}
return StructOrError.fromError(
"Cluster " + clusterName + ": unsupported built-in discovery type: " + type);
}
static io.envoyproxy.envoy.config.cluster.v3.OutlierDetection validateOutlierDetection(
io.envoyproxy.envoy.config.cluster.v3.OutlierDetection outlierDetection)
throws ResourceInvalidException {
if (outlierDetection.hasInterval()) {
if (!Durations.isValid(outlierDetection.getInterval())) {
throw new ResourceInvalidException("outlier_detection interval is not a valid Duration");
}
if (hasNegativeValues(outlierDetection.getInterval())) {
throw new ResourceInvalidException("outlier_detection interval has a negative value");
}
}
if (outlierDetection.hasBaseEjectionTime()) {
if (!Durations.isValid(outlierDetection.getBaseEjectionTime())) {
throw new ResourceInvalidException(
"outlier_detection base_ejection_time is not a valid Duration");
}
if (hasNegativeValues(outlierDetection.getBaseEjectionTime())) {
throw new ResourceInvalidException(
"outlier_detection base_ejection_time has a negative value");
}
}
if (outlierDetection.hasMaxEjectionTime()) {
if (!Durations.isValid(outlierDetection.getMaxEjectionTime())) {
throw new ResourceInvalidException(
"outlier_detection max_ejection_time is not a valid Duration");
}
if (hasNegativeValues(outlierDetection.getMaxEjectionTime())) {
throw new ResourceInvalidException(
"outlier_detection max_ejection_time has a negative value");
}
}
if (outlierDetection.hasMaxEjectionPercent()View on GitHub (pinned to 64daddc1f3)
Solutions
- Correct base_ejection_time to a valid Duration, e.g. {seconds: 30}.
- Remove the field if you want the default base ejection time.
- Validate the CDS response with a protobuf Duration validator before pushing it.
- Fix the emitting control plane's duration serialization (normalize nanos into seconds).
Example fix
# before
outlier_detection:
base_ejection_time: { nanos: 30000000000 }
# after
outlier_detection:
base_ejection_time: { seconds: 30 } Defensive patterns
Strategy: validation
Validate before calling
boolean validBaseEjectionTime(com.google.protobuf.Duration d) {
return com.google.protobuf.util.Durations.isValid(d)
&& d.getNanos() >= 0 && d.getNanos() < 1000000000;
} Type guard
boolean isValidProtoDuration(com.google.protobuf.Duration d) {
return d != null && com.google.protobuf.util.Durations.isValid(d);
} Try / catch
try {
parseCluster(resource);
} catch (io.grpc.xds.ResourceInvalidException e) {
if (e.getMessage().contains("base_ejection_time")) {
log.error("CDS resource rejected: fix base_ejection_time on the management server");
}
} Prevention
- Normalize durations so nanos stay within [0, 999999999] before serialization.
- Round-trip test configs through Durations.isValid before publishing.
- Use well-known helper functions (Durations.fromSeconds) instead of hand-built Durations.
- Avoid writing duration JSON by hand; generate it from typed values.
When it happens
Trigger: A Cluster resource from the xDS server carries outlier_detection.base_ejection_time with an invalid Duration value — nanos outside [0, 999999999] or seconds outside the representable range — detected in parseNonAggregateCluster via validateOutlierDetection.
Common situations: Malformed proto-JSON like {nanos: 1000000000} instead of {seconds: 1}; control-plane serialization bugs; hand-crafted test fixtures with placeholder durations; mixing -inf/NaN-like sentinels into duration fields.
Understand the failure class
Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.
Related errors
- outlier_detection interval has a negative value
- outlier_detection base_ejection_time has a negative value
- outlier_detection max_ejection_time is not a valid Duration
- outlier_detection max_ejection_time has a negative value
- unsupported ExtAuthz service type: only grpc_service is supp
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/9156e3c6d71ff566.
Report an issue: GitHub.