OpenFeign/feign · error · IOException

Mark not supported

Error message

Mark not supported

What it means

Micrometer's CountingInputStream.reset() throws IOException("Mark not supported") when the wrapped InputStream does not support mark/reset. The stream must be re-readable for metrics metering of request bodies, and reset() is only valid when the underlying stream advertises markSupported().

Solutions

  1. Wrap the input stream in BufferedInputStream before MeteredClient sees it (BufferedInputStream supports mark)
  2. Fix the custom Client to return a mark-supporting stream
  3. Avoid code paths that reset the response stream; consume it once
  4. If you control the source, buffer the body into a ByteArrayInputStream

Example fix

// before
return new MeteredInputStream(registry, conn.getInputStream(), ...);
// after
return new MeteredInputStream(registry, new BufferedInputStream(conn.getInputStream()), ...);
Defensive patterns

Strategy: validation

Validate before calling

InputStream raw = conn.getInputStream();
if (!raw.markSupported()) raw = new BufferedInputStream(raw);

Type guard

boolean resetSafe(InputStream is){ return is.markSupported(); }

Try / catch

try { stream.reset(); }
catch (IOException e) {
  if ("Mark not supported".equals(e.getMessage())) throw new IllegalStateException("wrap stream in BufferedInputStream", e);
  throw e;
}

Prevention

When it happens

Trigger: The underlying Client's stream (e.g. a raw socket stream from HttpURLConnection without buffering) lacks mark support and something calls reset() on the metered stream.

Common situations: Custom Client implementations returning non-buffered streams; retry logic or repeated body reads forcing a reset on a non-markable stream (e.g. chunked transfer streams).

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of OpenFeign/feign@e2a1e27560 (2026-09-10). Data as JSON: /api/errors/032f90e2ca3b98ad. Report an issue: GitHub.

Appendix: source

Thrown at micrometer/src/main/java/feign/micrometer/CountingInputStream.java:85

  @Override
  public long skip(long n) throws IOException {
    final long result = in.skip(n);
    count += result;
    return result;
  }

  @Override
  public synchronized void mark(int readlimit) {
    in.mark(readlimit);
    mark = count;
    // it's okay to mark even if mark isn't supported, as reset won't work
  }

  @Override
  public synchronized void reset() throws IOException {
    if (!in.markSupported()) {
      throw new IOException("Mark not supported");
    }
    if (mark == -1) {
      throw new IOException("Mark not set");
    }

    in.reset();
    count = mark;
  }
}

View on GitHub (pinned to e2a1e27560)