{"record":{"id":"e2f5f63151d7614d","repo":"eclipse-vertx/vert.x","slug":"contentlength-must-be-0","errorCode":null,"errorMessage":"contentLength must be >= 0","messagePattern":"contentLength must be >= 0","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/http/impl/HttpUtils.java","lineNumber":986,"sourceCode":"   */\n  public static HostAndPort socketAddressToHostAndPort(SocketAddress socketAddress) {\n    if (socketAddress instanceof InetSocketAddress) {\n      InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress;\n      return new HostAndPortImpl(inetSocketAddress.getHostString(), inetSocketAddress.getPort());\n    }\n    return null;\n  }\n\n  private static final String[] SMALL_POSITIVE_LONGS = new String[256];\n\n  /**\n   * This try hard to cache the first 256 positive longs as strings [0, 255] to avoid the cost of creating a new\n   * string for each of them.<br>\n   * The size/capacity of the cache is subject to change but this method is expected to be used for hot and frequent code paths.\n   */\n  public static String positiveLongToString(long value) {\n    if (value < 0) {\n      throw new IllegalArgumentException(\"contentLength must be >= 0\");\n    }\n    if (value >= SMALL_POSITIVE_LONGS.length) {\n      return Long.toString(value);\n    }\n    final int index = (int) value;\n    String str = SMALL_POSITIVE_LONGS[index];\n    if (str == null) {\n      // it's ok to be racy here, String is immutable hence it benefits from safe publication!\n      str = Long.toString(value);\n      SMALL_POSITIVE_LONGS[index] = str;\n    }\n    return str;\n  }\n\n  public static List<String> fromHttpAlpnVersions(List<io.vertx.core.http.HttpVersion> alpnVersions) {\n    return alpnVersions\n      .stream()\n      .map(io.vertx.core.http.HttpVersion::alpnName)","sourceCodeStart":968,"sourceCodeEnd":1004,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/http/impl/HttpUtils.java#L968-L1004","documentation":"HttpUtils.positiveLongToString(long) converts non-negative longs to String, caching the first 256 values for hot paths (used e.g. for content-length rendering). It throws IllegalArgumentException(\"contentLength must be >= 0\") when given a negative value, because a negative length is meaningless for HTTP message bodies. The message points at its main caller: rendering the Content-Length header of a request or response.","triggerScenarios":"Writing an HTTP request/response whose declared body length is negative — e.g. rendering Content-Length from a computed length of -1, passing a negative contentLength into an API that renders the header via positiveLongToString, or computing length via an underflowing subtraction (total - consumed).","commonSituations":"Initializing a length counter to -1 and forgetting to set it before sending; subtraction producing a negative result; file/stream size APIs returning -1 for missing or unreadable resources; a -1 'unknown length' sentinel leaking into the send path.","solutions":["Find where the negative length originates (log inputs before the call) and fix the computation or initialization so the value is >= 0.","Treat -1 as 'unknown length': use chunked transfer encoding (no Content-Length) instead of sending a negative value.","Check that file/stream size sources (e.g. File#length) are not returning -1 for missing/unreadable resources and handle that case before writing.","Guard the caller: validate length >= 0 before invoking the send/putHeader path."],"exampleFix":"// before\nlong len = file.length() - offset; // can be negative\nrequest.putHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(len));\n// after\nlong len = file.length() - offset;\nif (len < 0) {\n  request.setChunked(true); // unknown length -> chunked, no Content-Length\n} else {\n  request.putHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(len));\n}","handlingStrategy":"validation","validationCode":"if (contentLength < 0) {\n  throw new IllegalArgumentException(\"contentLength must be >= 0, got \" + contentLength);\n}\n// proceed with putHeader(CONTENT_LENGTH, String.valueOf(contentLength));","typeGuard":"public static boolean isNonNegative(long v) { return v >= 0; }\n// if (isNonNegative(len)) { putHeader(...); } else { setChunked(true); }","tryCatchPattern":"try {\n  sendRequestWithLength(len);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"contentLength\")) {\n    log.error(\"Negative content length computed: {}\", len);\n    // resend chunked or abort with a 500\n  } else {\n    throw e;\n  }\n}","preventionTips":["Never use -1 as an in-flight sentinel for 'unset' length in variables that reach the send path; use OptionalLong or a separate boolean.","Assert lengths are >= 0 at boundaries (file size reads, buffer size, total - consumed arithmetic).","Prefer chunked transfer encoding when the body length is unknown instead of a placeholder length.","Unit-test length computation with edge inputs (empty body, offset >= size)."],"tags":["http","content-length","validation","vertx-core"],"backgroundTag":"invalid-argument-value","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}