grpc/grpc-java · error · GrpcServiceParseException
Timeout must be strictly positive and valid
Error message
Timeout must be strictly positive and valid
What it means
Thrown by GrpcServiceConfigParser.parse when the GrpcService proto has a timeout that is either an invalid protobuf Duration (Durations.isValid fails, e.g. nanos out of [-999999999,999999999] with wrong seconds sign conventions) or is not strictly positive (zero or negative). xDS-provided GrpcService timeouts must represent a valid, positive duration.
Source
Thrown at xds/src/main/java/io/grpc/xds/GrpcServiceConfigParser.java:120
if (key.endsWith(Metadata.BINARY_HEADER_SUFFIX)) {
headerValue = HeaderValue.create(key, header.getRawValue());
} else {
headerValue = HeaderValue.create(key, header.getValue());
}
} catch (IllegalArgumentException e) {
throw new GrpcServiceParseException("Invalid initial metadata header: " + key, e);
}
if (HeaderValueValidationUtils.isDisallowed(headerValue)) {
throw new GrpcServiceParseException("Invalid initial metadata header: " + key);
}
initialMetadata.add(headerValue);
}
builder.initialMetadata(initialMetadata.build());
if (grpcServiceProto.hasTimeout()) {
com.google.protobuf.Duration timeout = grpcServiceProto.getTimeout();
if (!Durations.isValid(timeout) || Durations.compare(timeout, Durations.ZERO) <= 0) {
throw new GrpcServiceParseException("Timeout must be strictly positive and valid");
}
builder.timeout(Duration.ofSeconds(timeout.getSeconds(), timeout.getNanos()));
}
return builder.build();
}
/**
* Parses the {@link io.envoyproxy.envoy.config.core.v3.GrpcService.GoogleGrpc} proto to create a
* {@link GrpcServiceConfig.GoogleGrpcConfig} instance.
*
* @param googleGrpcProto The proto to parse.
* @return A {@link GrpcServiceConfig.GoogleGrpcConfig} instance.
* @throws GrpcServiceParseException if the proto is invalid.
*/
public static GrpcServiceConfig.GoogleGrpcConfig parseGoogleGrpcConfig(
GrpcService.GoogleGrpc googleGrpcProto, Bootstrapper.BootstrapInfo bootstrapInfo,
Bootstrapper.ServerInfo serverInfo) throws GrpcServiceParseException {
View on GitHub (pinned to 64daddc1f3)
Solutions
- Set a strictly positive timeout (e.g. seconds >= 1) in the GrpcService proto, or omit the timeout field entirely.
- Fix the control-plane resource generator to emit canonical protobuf Duration values.
- If a zero timeout was intended as 'no timeout', remove the field rather than sending zero.
Example fix
// before (xDS resource)
timeout { seconds: 0 nanos: 0 }
// after
timeout { seconds: 10 nanos: 0 } // or remove the field Defensive patterns
Strategy: validation
Validate before calling
// Validate timeout before deploying the resource
com.google.protobuf.Duration t = grpcServiceProto.getTimeout();
boolean ok = !grpcServiceProto.hasTimeout()
|| (Durations.isValid(t) && Durations.compare(t, Durations.ZERO) > 0);
if (!ok) throw new IllegalArgumentException("GrpcService timeout must be strictly positive"); Try / catch
try {
config = GrpcServiceConfigParser.parse(proto, bootstrapInfo, serverInfo);
} catch (GrpcServiceParseException e) {
if (e.getMessage().contains("Timeout")) {
// treat as invalid resource, request corrected config from control plane
}
} Prevention
- Omit the timeout field instead of sending zero when no timeout is intended
- Generate Duration values via protobuf helpers (Durations.fromSeconds) to keep them canonical
- Add control-plane unit tests asserting positive canonical durations
When it happens
Trigger: The xDS management server sends GrpcService.timeout as Duration{seconds:0, nanos:0} or a negative value, or a malformed Duration that fails Durations.isValid (e.g. nanos beyond 1 second bounds with inconsistent seconds sign).
Common situations: Control-plane bug emitting zero timeouts; hand-crafted test resources with timeout left at default zero; protobuf Duration serialization issues in custom control planes.
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.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Duration is not valid. See proto definition for valid values
- Invalid initial metadata header: ${key}
- Invalid initial metadata header: " + key
- Target URI scheme is not resolvable: " + targetUri
- Invalid duration in weighted round robin config: " + ex.getM
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/fbd8dd52c0ecd16d.
Report an issue: GitHub.