nostra13/Android-Universal-Image-Loader · error · IllegalArgumentException

URI [%1$s] doesn't have expected scheme [%2$s]

Error message

URI [%1$s] doesn't have expected scheme [%2$s]

What it means

Scheme.crop() (on the Scheme enum inside ImageDownloader) strips a known prefix like "http://" from a URI and throws IllegalArgumentException if the URI doesn't actually start with that scheme's prefix. It is a strict precondition: you must only call crop() on URIs already verified to belong to that scheme (typically via belongsTo() or Scheme.ofUri()). The format embeds both the offending URI and the expected scheme.

Source

Thrown at library/src/main/java/com/nostra13/universalimageloader/core/download/ImageDownloader.java:85

					}
				}
			}
			return UNKNOWN;
		}

		private boolean belongsTo(String uri) {
			return uri.toLowerCase(Locale.US).startsWith(uriPrefix);
		}

		/** Appends scheme to incoming path */
		public String wrap(String path) {
			return uriPrefix + path;
		}

		/** Removed scheme part ("scheme://") from incoming URI */
		public String crop(String uri) {
			if (!belongsTo(uri)) {
				throw new IllegalArgumentException(String.format("URI [%1$s] doesn't have expected scheme [%2$s]", uri, scheme));
			}
			return uri.substring(uriPrefix.length());
		}
	}
}

View on GitHub (pinned to ba33ec64d0)

Solutions

  1. Guard crop() with belongsTo() (or match on Scheme.ofUri(uri)) before calling it
  2. Use the correct enum constant for the URI you hold — HTTPS.crop for https:// URIs
  3. Keep data symmetric: only crop values produced by wrap(), and wrap again before displayImage
  4. Normalize URIs to a known scheme at the data boundary (DB/model layer) so crop sites can trust them

Example fix

// before
String path = Scheme.HTTP.crop(uri); // throws if uri is https:// or file://

// after
Scheme scheme = Scheme.ofUri(uri);
if (scheme == Scheme.HTTP) {
    String path = Scheme.HTTP.crop(uri);
} else {
    throw new IllegalArgumentException("Unexpected scheme for " + uri);
}
Defensive patterns

Strategy: validation

Validate before calling

String prefix = scheme.wrap(""); // e.g. "http://"
if (uri != null && uri.toLowerCase(Locale.US).startsWith(prefix)) {
    String path = scheme.crop(uri);
} else {
    throw new IllegalArgumentException("URI " + uri + " is not " + prefix);
}

Type guard

private static boolean belongsToScheme(String uri, ImageDownloader.Scheme scheme) {
    return uri != null && uri.toLowerCase(Locale.US).startsWith(scheme.wrap(""));
}

Try / catch

try {
    path = Scheme.HTTP.crop(uri);
} catch (IllegalArgumentException e) {
    // URI/expected scheme mismatch: re-detect scheme or reject the record
    LOG.warn("Wrong scheme for {}", uri);
    path = uri;
}

Prevention

When it happens

Trigger: Calling Scheme.HTTP.crop(uri) on a URI like "file:///path" or "https://host" (HTTPS cropped with the HTTP enum); calling crop() before checking belongsTo(); calling crop(""+id) where the stored value never had the scheme appended (forgetting wrap() on the same data path).

Common situations: Persisting cropped IDs and later re-cropping them a second time; mixed http/https data where the wrong enum constant is used; deserialized URIs whose scheme changed between write and read; defensive-code refactors that moved crop() before the scheme check.

Related errors


AI-assisted analysis of nostra13/Android-Universal-Image-Loader@ba33ec64d0 (2026-08-14). Data as JSON: /api/errors/7b839e7faa4af0cd. Report an issue: GitHub.