grpc/grpc-java · error · IOException
Can not initialize. The env variable GRPC_BINARY_LOG_CONFIG…
Error message
Can not initialize. The env variable GRPC_BINARY_LOG_CONFIG must be valid.
What it means
BinaryLogProviderImpl's constructor wraps a RuntimeException from BinlogHelper.FactoryImpl (parsing the GRPC_BINARY_LOG_CONFIG string) into an IOException with this message, after closing the sink. It means the binary log configuration string is blank or syntactically invalid, so binary logging cannot be initialized.
Solutions
- Fix the GRPC_BINARY_LOG_CONFIG value to a valid pattern list, e.g. '*{h:2;m:100}' or 'my.Service/Method{h}'
- Ensure the value is not blank and entries use service[/method]{options} syntax separated appropriately
- Check for duplicate '*' (global) entries in the config string
- Test the config string locally by running FactoryImpl parsing before deploying
Example fix
// before
GRPC_BINARY_LOG_CONFIG=""
// after
GRPC_BINARY_LOG_CONFIG="*{h:2;m:100}" Defensive patterns
Strategy: validation
Validate before calling
String cfg = System.getenv("GRPC_BINARY_LOG_CONFIG");
if (cfg == null || cfg.trim().isEmpty()) {
throw new IllegalStateException("GRPC_BINARY_LOG_CONFIG is blank; set e.g. \"*{h:2;m:100}\"");
}
// sanity: entries must be service[/method]{opts} or *{opts}
for (String entry : cfg.split(",")) {
if (!entry.matches("^(\\*|[A-Za-z0-9_.]+(/[A-Za-z0-9_.]+)?)\\{[^}]*\\}$")) {
throw new IllegalStateException("Bad binlog entry: " + entry);
}
} Try / catch
try {
BinaryLogProviderImpl provider = new BinaryLogProviderImpl(sink, configStr);
} catch (IOException e) {
logger.atWarning().withCause(e).log("Invalid GRPC_BINARY_LOG_CONFIG; disabling binary log");
} Prevention
- Validate the env var value in CI before deploy
- Use documented syntax: comma-separated service[/method]{h;m} entries
- Never leave GRPC_BINARY_LOG_CONFIG blank when binary logging is enabled
When it happens
Trigger: Constructing BinaryLogProviderImpl (e.g. via grpc-services binary log setup) where new BinlogHelper.FactoryImpl(sink, configStr) throws because configStr is blank, malformed, or contains duplicate/invalid entries.
Common situations: Setting the GRPC_BINARY_LOG_CONFIG env var to an empty value, a typo like 'svc{}' or 'foo{h:}' , or a string with a duplicate '*' entry when wiring up gRPC binary logging.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Illegal log config pattern:
- Illegal log config pattern
- Fail to read bootstrap file
- Matcher tree depth exceeds limit of 16
- No trust roots configured
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/9e566e7fb0e3035d.
Report an issue: GitHub.
Appendix: source
Thrown at services/src/main/java/io/grpc/protobuf/services/BinaryLogProviderImpl.java:63
@SuppressWarnings("InlineMeSuggester") // Only called internally; don't care
public BinaryLogProviderImpl(BinaryLogSink sink) throws IOException {
this(sink, System.getenv("GRPC_BINARY_LOG_CONFIG"));
}
/**
* Creates an instance.
* @param sink ownership is transferred to this class.
* @param configStr config string to parse to determine logged methods and msg size limits.
* @throws IOException if initialization failed.
*/
public BinaryLogProviderImpl(BinaryLogSink sink, String configStr) throws IOException {
this.sink = Preconditions.checkNotNull(sink);
try {
factory = new BinlogHelper.FactoryImpl(sink, configStr);
} catch (RuntimeException e) {
sink.close();
// parsing the conf string may throw if it is blank or contains errors
throw new IOException(
"Can not initialize. The env variable GRPC_BINARY_LOG_CONFIG must be valid.", e);
}
}
@Nullable
@Override
public ServerInterceptor getServerInterceptor(String fullMethodName) {
BinlogHelper helperForMethod = factory.getLog(fullMethodName);
if (helperForMethod == null) {
return null;
}
return helperForMethod.getServerInterceptor(counter.getAndIncrement());
}
@Nullable
@Override
public ClientInterceptor getClientInterceptor(
String fullMethodName, CallOptions callOptions) {View on GitHub (pinned to 64daddc1f3)