{"record":{"id":"590dcff888aa5342","repo":"bumptech/glide","slug":"received-empty-or-null-redirect-url","errorCode":null,"errorMessage":"Received empty or null redirect url","messagePattern":"Received empty or null redirect url","errorType":"http","errorClass":"HttpException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/bumptech/glide/load/data/HttpUrlFetcher.java","lineNumber":112,"sourceCode":"      urlConnection.connect();\n      // Set the stream so that it's closed in cleanup to avoid resource leaks. See #2352.\n      stream = urlConnection.getInputStream();\n    } catch (IOException e) {\n      throw new HttpException(\n          \"Failed to connect or obtain data\", getHttpStatusCodeOrInvalid(urlConnection), e);\n    }\n\n    if (isCancelled) {\n      return null;\n    }\n\n    final int statusCode = getHttpStatusCodeOrInvalid(urlConnection);\n    if (isHttpOk(statusCode)) {\n      return getStreamForSuccessfulRequest(urlConnection);\n    } else if (isHttpRedirect(statusCode)) {\n      String redirectUrlString = urlConnection.getHeaderField(REDIRECT_HEADER_FIELD);\n      if (TextUtils.isEmpty(redirectUrlString)) {\n        throw new HttpException(\"Received empty or null redirect url\", statusCode);\n      }\n      URL redirectUrl;\n      try {\n        redirectUrl = new URL(url, redirectUrlString);\n      } catch (MalformedURLException e) {\n        throw new HttpException(\"Bad redirect url: \" + redirectUrlString, statusCode, e);\n      }\n      // Closing the stream specifically is required to avoid leaking ResponseBodys in addition\n      // to disconnecting the url connection below. See #2352.\n      cleanup();\n      return loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);\n    } else if (statusCode == INVALID_STATUS_CODE) {\n      throw new HttpException(statusCode);\n    } else {\n      try {\n        throw new HttpException(urlConnection.getResponseMessage(), statusCode);\n      } catch (IOException e) {\n        throw new HttpException(\"Failed to get a response message\", statusCode, e);","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/bumptech/glide/blob/eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a/library/src/main/java/com/bumptech/glide/load/data/HttpUrlFetcher.java#L94-L130","documentation":"When the server returns a 3xx redirect status code, HttpUrlFetcher reads the Location header to determine the redirect target. If the Location header is empty or missing (TextUtils.isEmpty returns true), the redirect response is malformed and Glide cannot follow it, so it throws an HttpException with the redirect status code.","triggerScenarios":"Server returns 301 Moved Permanently or 302 Found but omits or sends a blank Location header. A reverse proxy strips the Location header. A server bug returns a redirect status without the corresponding header.","commonSituations":"Misconfigured web servers or CDNs. Custom server-side redirect logic that forgets to set the Location header. API gateways that proxy redirects incorrectly.","solutions":["Fix the server to always include a valid Location header on 3xx responses","Provide the direct (non-redirecting) image URL to Glide","Handle the HttpException in RequestListener and show a fallback image"],"exampleFix":"// before\nGlide.with(context).load(redirectingUrl).into(imageView);\n// after — use direct URL and handle failure\nGlide.with(context)\n  .load(directImageUrl)\n  .error(R.drawable.placeholder)\n  .into(imageView);","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"Glide.with(context)\n  .load(url)\n  .error(R.drawable.placeholder)\n  .listener(new RequestListener<Drawable>() {\n    @Override public boolean onLoadFailed(GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {\n      for (Throwable cause : e.getRootCauses()) {\n        if (cause instanceof HttpException && cause.getMessage().contains(\"empty or null redirect\")) {\n          Log.w(TAG, \"Server sent redirect without Location header for \" + model);\n        }\n      }\n      return false;\n    }\n    @Override public boolean onResourceReady(Drawable r, Object m, Target<Drawable> t, DataSource d, boolean i) { return false; }\n  })\n  .into(imageView);","preventionTips":["Use direct image URLs that do not require redirects","Fix server-side redirect responses to always include a valid Location header","Monitor server responses for malformed 3xx status codes"],"tags":["glide","http","redirect","network"],"backgroundTag":null,"analyzedSha":"eb14a895d8f866e6a08c3e19d50ea3bd2c12c20a","analyzedAt":"2026-08-14T01:43:54.821Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}