{"record":{"id":"de76ddba59e09e0c","repo":"zxing/zxing","slug":"no-location","errorCode":null,"errorMessage":"No Location","messagePattern":"No Location","errorType":"http","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"android/src/com/google/zxing/client/android/HttpHelper.java","lineNumber":118,"sourceCode":"      URL url = new URL(uri);\n      HttpURLConnection connection = safelyOpenConnection(url);\n      connection.setInstanceFollowRedirects(true); // Won't work HTTP -> HTTPS or vice versa\n      connection.setRequestProperty(\"Accept\", contentTypes);\n      connection.setRequestProperty(\"Accept-Charset\", \"utf-8,*\");\n      connection.setRequestProperty(\"User-Agent\", \"ZXing (Android)\");\n      try {\n        int responseCode = safelyConnect(connection);\n        switch (responseCode) {\n          case HttpURLConnection.HTTP_OK:\n            return consume(connection, maxChars);\n          case HttpURLConnection.HTTP_MOVED_TEMP:\n            String location = connection.getHeaderField(\"Location\");\n            if (location != null) {\n              uri = location;\n              redirects++;\n              continue;\n            }\n            throw new IOException(\"No Location\");\n          default:\n            throw new IOException(\"Bad HTTP response: \" + responseCode);\n        }\n      } finally {\n        connection.disconnect();\n      }\n    }\n    throw new IOException(\"Too many redirects\");\n  }\n\n  private static String getEncoding(URLConnection connection) {\n    String contentTypeHeader = connection.getHeaderField(\"Content-Type\");\n    if (contentTypeHeader != null) {\n      int charsetStart = contentTypeHeader.indexOf(\"charset=\");\n      if (charsetStart >= 0) {\n        return contentTypeHeader.substring(charsetStart + \"charset=\".length());\n      }\n    }","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/zxing/zxing/blob/19aa2d8254410e161f04dc3c928e68d5e90233c2/android/src/com/google/zxing/client/android/HttpHelper.java#L100-L136","documentation":"Thrown by HttpHelper.downloadViaHttp when an HTTP 302 (HTTP_MOVED_TEMP) response is received but the server omitted the 'Location' response header. ZXing follows redirects manually (up to 5 hops) because Android's HttpURLConnection cannot follow redirects across scheme changes (HTTP->HTTPS). A 302 with no Location is a malformed redirect that cannot be followed.","triggerScenarios":"downloadViaHttp(uri, type, maxChars) receives a response with code 302 but connection.getHeaderField(\"Location\") returns null. This happens with broken URL shorteners (bit.ly, t.co, goo.gl), misconfigured reverse proxies, or servers that send 302 without a Location header.","commonSituations":"Scanning a barcode containing a shortened or redirected URL whose redirect endpoint is misconfigured. A CDN or load balancer returning 302 without Location during a maintenance window. The domain listed in REDIRECTOR_DOMAINS whose service is temporarily broken.","solutions":["Verify the URL resolves correctly in a browser or with curl -I to inspect the redirect chain and Location header.","If you control the server, ensure all 302/301 responses include a valid absolute or relative Location header.","Catch IOException around downloadViaHttp and show a user-friendly message instead of crashing.","Retry the request once after a short delay, as transient server misconfigurations can resolve."],"exampleFix":"// before\nCharSequence result = HttpHelper.downloadViaHttp(uri, HttpHelper.ContentType.HTML, 8192);\n\n// after\nCharSequence result;\ntry {\n  result = HttpHelper.downloadViaHttp(uri, HttpHelper.ContentType.HTML, 8192);\n} catch (IOException e) {\n  // Surface a user-friendly message; log the failed URI for debugging\n  result = null;\n  Log.w(TAG, \"Download failed for \" + uri + \": \" + e.getMessage());\n}","handlingStrategy":"try-catch","validationCode":"// No reliable pre-check exists for server redirect behavior.\n// Validate the URI scheme before the call:\nif (uri == null || !(uri.startsWith(\"http://\") || uri.startsWith(\"https://\"))) {\n  // Skip download for non-HTTP URIs\n  return;\n}","typeGuard":"if (uri instanceof String && (uri.startsWith(\"http://\") || uri.startsWith(\"https://\"))) {\n  // safe to call downloadViaHttp\n}","tryCatchPattern":"try {\n  CharSequence content = HttpHelper.downloadViaHttp(uri, type, maxChars);\n} catch (IOException e) {\n  if (\"No Location\".equals(e.getMessage())) {\n    // Malformed redirect; surface original URI to user\n    openInBrowser(uri);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Validate URIs are HTTP/HTTPS before calling downloadViaHttp.","Wrap all HttpHelper calls in try-catch IOException and provide fallback behavior.","Pre-resolve known shortener URLs through a redirect-resolution service if you need stability."],"tags":["network","http","redirect","android"],"backgroundTag":null,"analyzedSha":"19aa2d8254410e161f04dc3c928e68d5e90233c2","analyzedAt":"2026-08-14T03:07:53.428Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}