CarGuo/GSYVideoPlayer · error · IllegalStateException
Error starting local proxy server
Error message
Error starting local proxy server
What it means
HttpUrlSource.open(offset) opens an HttpURLConnection (following manual redirect handling), reads content type/length, and stores SourceInfo. Any IOException during connect, getInputStream, or header parsing becomes a ProxyCacheException naming the url and offset. This is the proxy's main 'could not reach the origin server for this byte range' error.
Source
Thrown at gsyVideoPlayer-proxy_cache/src/main/java/com/danikula/videocache/HttpProxyCacheServer.java:86
this(new Builder(context).buildConfig());
}
private HttpProxyCacheServer(Config config) {
this.config = checkNotNull(config);
try {
InetAddress inetAddress = InetAddress.getByName(PROXY_HOST);
this.serverSocket = new ServerSocket(0, 8, inetAddress);
this.port = serverSocket.getLocalPort();
IgnoreHostProxySelector.install(PROXY_HOST, port);
CountDownLatch startSignal = new CountDownLatch(1);
this.waitConnectionThread = new Thread(new WaitRequestsRunnable(startSignal));
this.waitConnectionThread.start();
startSignal.await(); // freeze thread, wait for server starts
this.pinger = new Pinger(PROXY_HOST, port);
HttpProxyCacheDebuger.printfLog("Proxy cache server started. Is it alive? " + isAlive());
} catch (IOException | InterruptedException e) {
socketProcessor.shutdown();
throw new IllegalStateException("Error starting local proxy server", e);
}
}
/**
* Returns url that wrap original url and should be used for client (MediaPlayer, ExoPlayer, etc).
* <p>
* If file for this url is fully cached (it means method {@link #isCached(String)} returns {@code true})
* then file:// uri to cached file will be returned.
* <p>
* Calling this method has same effect as calling {@link #getProxyUrl(String, boolean)} with 2nd parameter set to {@code true}.
*
* @param url a url to file that should be cached.
* @return a wrapped by proxy url if file is not fully cached or url pointed to cache file otherwise.
*/
public String getProxyUrl(String url) {
return getProxyUrl(url, true);
}
View on GitHub (pinned to e5d74d3aa9)
Solutions
- Refresh the playback URL (re-fetch signed token URL) before seeking or on error and restart playback via GSYVideoPlayer
- Implement a custom HttpUrlSource with a HeaderInjector that injects fresh auth tokens/referer for each request
- Add retry-once logic around player start in onError of GSYVideoViewBuilder
- Verify the URL supports Range requests (Accept-Ranges header) or use an origin that does
Example fix
// before
proxyCacheServer.getProxyUrl(expiredSignedUrl);
// after - inject fresh headers per request via HeaderInjector
public class AuthHeaderInjector implements HeaderInjector {
@Override
public Map<String, String> addHeaders(String url) {
Map<String, String> h = new HashMap<>();
h.put("Authorization", "Bearer " + TokenStore.current());
return h;
}
}
new HttpProxyCacheServer.Builder(context).headerInjector(new AuthHeaderInjector()).build(); Defensive patterns
Strategy: retry
Validate before calling
// cheap pre-flight before handing url to the proxy
HttpURLConnection c = (HttpURLConnection) new URL(url).openConnection();
c.setRequestMethod("HEAD");
int code = c.getResponseCode(); // 2xx expected; catch IOException before proxy does Try / catch
try { play(proxy.getProxyUrl(url)); }
catch (ProxyCacheException e) {
if (String.valueOf(e.getMessage()).contains("Error opening connection")) {
url = refreshSignedUrl(); play(proxy.getProxyUrl(url)); // one retry with fresh url
} else throw e;
} Prevention
- Refresh signed/expiring urls right before playback, not at list-load time
- Inject auth headers via HeaderInjector instead of baking tokens into urls
- Confirm the origin supports range requests
When it happens
Trigger: ProxyCache requests a range (offset > 0 after a seek) and the origin returns connection reset / 416 / DNS failure / TLS error; openConnection follows more than MAX_REDIRECTS(5) hops is handled separately, but socket timeouts and unreachable hosts land here; an invalid Content-Length header (Long.parseLong) also throws here.
Common situations: Expired signed CDN URLs (token in query string no longer valid when the proxy re-requests ranges); server dropping keep-alive connections causing connection reset on seek; device behind a captive portal; server not supporting Range requests while the proxy opens with an offset; malformed Content-Length header (non-numeric).
Related errors
- Error reading data from ${sourceInfo.url}
- Error opening connection for ${sourceInfo.url} with offset $
- Reading source ${sourceInfo.url} is interrupted
- Too many redirects: ${redirectCount}
- Error reading source ${errorsCount} times
AI-assisted analysis of CarGuo/GSYVideoPlayer@e5d74d3aa9 (2026-08-14).
Data as JSON: /api/errors/b1cf881ec73719a3.
Report an issue: GitHub.