didi/DoKit · error · ProtocolException

This protocol does not support input

Error message

This protocol does not support input

What it means

HttpURLConnection.getInputStream() honors the doInput flag; when doInput is false the wrapper throws ProtocolException("This protocol does not support input") before attempting getResponse(). doInput defaults to true, so this only happens when setDoInput(false) was called explicitly (or setUseCaches/doInput state was misconfigured).

Source

Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/urlconnection/ObsoleteUrlFactory.java:455

            } catch (IOException e) {
                return Collections.emptyMap();
            }
        }

        @Override
        public Map<String, List<String>> getRequestProperties() {
            if (connected) {
                throw new IllegalStateException(
                        "Cannot access request header fields after connection is set");
            }

            return toMultimap(requestHeaders.build(), null);
        }

        @Override
        public InputStream getInputStream() throws IOException {
            if (!doInput) {
                throw new ProtocolException("This protocol does not support input");
            }

            Response response = getResponse(false);
            if (response.code() >= HTTP_BAD_REQUEST) {
                Log.e("DoKit", "FileNotFoundException:" + url.toString());
                return ConvertUtils.string2InputStream("FileNotFoundException:" + url.toString(), "utf-8");
            }

            if (response.body() != null) {
                return response.body().byteStream();
            } else {
                return ConvertUtils.string2InputStream("response.body() is null:" + url.toString(), "utf-8");
            }

        }

        @Override
        public OutputStream getOutputStream() throws IOException {

View on GitHub (pinned to 626827cddb)

Solutions

  1. Do not call getInputStream() when you set setDoInput(false); remove one or the other.
  2. Leave doInput at its default true when you need to read the response (even just the status line/error body).
  3. If you only need the status code for an upload, call getResponseCode() with doInput left enabled.

Example fix

// before
conn.setDoOutput(true);
conn.setDoInput(false);
... write body ...
InputStream is = conn.getInputStream(); // ProtocolException

// after
conn.setDoOutput(true); // doInput stays true by default
... write body ...
InputStream is = conn.getInputStream();
Defensive patterns

Strategy: validation

Validate before calling

if (conn.getDoInput()) { readStream(conn.getInputStream()); } else { /* upload-only, skip read */ }

Prevention

When it happens

Trigger: Calling setDoInput(false) (e.g. for a pure upload) and then still calling getInputStream(); also getResponseCode()/getContent() after disabling input.

Common situations: Copy-pasted POST-upload snippets that call setDoOutput(true) plus setDoInput(false), followed by generic response-reading code that assumes getInputStream() always works.

Related errors


AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14). Data as JSON: /api/errors/2e7c06bc5db9da76. Report an issue: GitHub.