grpc/grpc-java · error · EOFException

\n not found: ${hex}

Error message

\n not found: ${hex}

What it means

readUtf8LineStrictUnbuffered throws EOFException when the HTTP/1.x proxy handshake response stream ends before a newline is found. The hex is the partial bytes read. It means the CONNECT response (or header line) was truncated — the peer closed the connection mid-response.

Source

Thrown at okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java:936

        .build();

    Request.Builder request = new Request.Builder()
        .url(tunnelUrl)
        .header("Host", tunnelUrl.host() + ":" + tunnelUrl.port())
        .header("User-Agent", userAgent);

    // If we have proxy credentials, set them right away
    if (proxyUsername != null && proxyPassword != null) {
      request.header("Proxy-Authorization", Credentials.basic(proxyUsername, proxyPassword));
    }
    return request.build();
  }

  private static String readUtf8LineStrictUnbuffered(Source source) throws IOException {
    Buffer buffer = new Buffer();
    while (true) {
      if (source.read(buffer, 1) == -1) {
        throw new EOFException("\\n not found: " + buffer.readByteString().hex());
      }
      if (buffer.getByte(buffer.size() - 1) == '\n') {
        return buffer.readUtf8LineStrict();
      }
    }
  }

  @Override
  public String toString() {
    return MoreObjects.toStringHelper(this)
        .add("logId", logId.getId())
        .add("address", address)
        .toString();
  }

  @Override
  public InternalLogId getLogId() {
    return logId;

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Fix or bypass the proxy (check https_proxy/HTTP_PROXY settings, proxy exclusions)
  2. Test connectivity directly without the proxy to confirm the proxy is truncating responses
  3. Retry the RPC; gRPC will re-establish the connection
  4. If the proxy is required, upgrade/fix it so it returns a complete CONNECT response with CRLF

Example fix

// before
OkHttpChannelBuilder.forAddress(host, port).proxyDetector(ProxyDetector.DEFAULT)... // bad proxy
// after
OkHttpChannelBuilder.forAddress(host, port) // bypass broken proxy
  .proxyDetector(targetSocketAddress -> ProxyHelper.noProxy())
  .build();
Defensive patterns

Strategy: retry

Validate before calling

// pre-check proxy reachability
Socket s = new Socket(); try { s.connect(proxyAddr, 5000); } finally { s.close(); }

Try / catch

try { stub.unaryCall(req); } catch (StatusRuntimeException e) { if (e.getStatus().getCode() == Status.Code.UNAVAILABLE) { retryWithBackoff(); } throw e; }

Prevention

When it happens

Trigger: Running through an HTTP proxy whose CONNECT response is cut off by the proxy or an intermediary; connection reset during handshake; proxy returning an empty or partial response body.

Common situations: Misconfigured corporate proxies, proxies that drop long-lived connections, transparent proxies/firewalls interfering with CONNECT, unstable networks cutting the socket early.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/1f9617356aa639e8. Report an issue: GitHub.