CarGuo/GSYVideoPlayer · error · ProxyCacheException

Too many redirects: ${redirectCount}

Error message

Too many redirects: ${redirectCount}

What it means

ProxyCache.readSource loop counts consecutive source read failures; before each (re)attempt it calls checkReadSourceErrorsCount, and because MAX_READ_SOURCE_ATTEMPTS is 1, the very first read error after a retry trigger throws ProxyCacheException('Error reading source 1 times'). This deliberately aborts the cache-filling loop instead of hammering a broken origin.

Source

Thrown at gsyVideoPlayer-proxy_cache/src/main/java/com/danikula/videocache/HttpUrlSource.java:213

                    }
                    connection.setRequestProperty("Range", "bytes=" + ofr + "-");
                } else {
                    connection.setRequestProperty("Range", "bytes=" + (int)offset + "-");
                }
            }
            if (timeout > 0) {
                connection.setConnectTimeout(timeout);
                connection.setReadTimeout(timeout);
            }
            int code = connection.getResponseCode();
            redirected = code == HTTP_MOVED_PERM || code == HTTP_MOVED_TEMP || code == HTTP_SEE_OTHER;
            if (redirected) {
                url = connection.getHeaderField("Location");
                redirectCount++;
                connection.disconnect();
            }
            if (redirectCount > MAX_REDIRECTS) {
                throw new ProxyCacheException("Too many redirects: " + redirectCount);
            }
        } while (redirected);
        return connection;
    }

    private void injectCustomHeaders(HttpURLConnection connection, String url) {
        Map<String, String> extraHeaders = headerInjector.addHeaders(url);
        if (extraHeaders == null) {
            return;
        }
        HttpProxyCacheDebuger.printfError("****** injectCustomHeaders ****** :" + extraHeaders.size());
        for (Map.Entry<String, String> header : extraHeaders.entrySet()) {
            connection.setRequestProperty(header.getKey(), header.getValue());
        }
    }

    public synchronized String getMime() throws ProxyCacheException {
        if (TextUtils.isEmpty(sourceInfo.mime)) {

View on GitHub (pinned to e5d74d3aa9)

Solutions

  1. Fix the underlying network/source error (see HttpUrlSource read errors) - this exception is a symptom, not the cause
  2. Wrap playback start in a retry that rebuilds the proxy url and resumes from cached offset
  3. Check disk space: a full disk during caching surfaces as read/append errors then this
  4. If you fork the library and want resilience, raise MAX_READ_SOURCE_ATTEMPTS and add backoff

Example fix

// before - propagate and kill playback
catch (Exception e) { player.stop(); }

// after - bounded resume attempt using already-cached bytes
int attempts = 0;
while (attempts++ < 2) {
    try { startOrResume(proxyCacheServer.getProxyUrl(url)); break; }
    catch (Exception e) { Log.w(TAG, "cache read failed, attempt " + attempts, e); }
}
Defensive patterns

Strategy: retry

Try / catch

catch (ProxyCacheException e) {
    if (String.valueOf(e.getMessage()).startsWith("Error reading source")) {
        // symptom of an earlier read failure: bounded resume attempt
        if (attempts++ < 2) resumeFromCachedOffset(url, position);
        else playDirect(url);
    } else throw e;
}

Prevention

When it happens

Trigger: The source reader thread gets a ProxyCacheException from HttpUrlSource.read (network drop, connection reset) while filling FileCache; on the next loop iteration the error count (already >= 1) trips this guard and the caching session is terminated.

Common situations: Any mid-stream network failure while proxy caching - same root causes as error 6/7 (network switch, server reset). This is the terminal aggregate exception the player's onError often receives after the underlying read failure.

Related errors


AI-assisted analysis of CarGuo/GSYVideoPlayer@e5d74d3aa9 (2026-08-14). Data as JSON: /api/errors/d82ac7ab2cb61206. Report an issue: GitHub.