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

  1. Fix the GRPC_BINARY_LOG_CONFIG value to a valid pattern list, e.g. '*{h:2;m:100}' or 'my.Service/Method{h}'
  2. Ensure the value is not blank and entries use service[/method]{options} syntax separated appropriately
  3. Check for duplicate '*' (global) entries in the config string
  4. 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

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


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)