# Troubleshooting Common issues and their solutions when deploying and using R2-Manager-Worker. ## Authentication Issues ### ❌ "Failed to authenticate" error **Symptoms:** - Cannot access the application - Redirected to login repeatedly - 401 Unauthorized errors in console **Solutions:** 1. **Verify TEAM_DOMAIN includes full URL:** ```bash npx wrangler secret put TEAM_DOMAIN # Enter: https://yourteam.cloudflareaccess.com ``` 2. **Confirm POLICY_AUD matches Application Audience Tag:** - Go to Zero Trust → **Access** → **Applications** → Select your app - Copy **Application Audience (AUD) Tag** from **Overview** tab - Set secret: `npx wrangler secret put POLICY_AUD` 3. **Check GitHub account is allowed:** - Go to Zero Trust → **Access** → **Applications** → Select your app - Review **Policies** tab - Ensure your GitHub account matches the Allow policy 4. **Clear browser cookies:** - Open DevTools (F12) → **Application** tab → **Cookies** - Delete all cookies for your domain - Try logging in again 5. **Verify JWT cookie is set:** - After logging in, check DevTools → **Application** → **Cookies** - Look for `cf-access-jwt-assertion` cookie - If missing, check Cloudflare Access configuration --- ## Bucket Issues ### ❌ "Bucket not found" error **Symptoms:** - Cannot list files in bucket - Error message: "Failed to list files" - 404 errors in Worker logs **Solutions:** 1. **Verify bucket exists:** ```bash npx wrangler r2 bucket list ``` 2. **Check bucket name in wrangler.toml:** ```toml [[r2_buckets]] binding = "BUCKET" bucket_name = "exact-bucket-name" # Must match exactly (case-sensitive) ``` 3. **Verify ACCOUNT_ID is correct:** - Go to [Cloudflare Dashboard](https://dash.cloudflare.com/) - Find Account ID in right sidebar - Update secret: `npx wrangler secret put ACCOUNT_ID` 4. **Check API token permissions:** - Go to [API Tokens page](https://dash.cloudflare.com/profile/api-tokens) - Verify token has **Workers R2 Storage → Edit** permission - If missing, create new token with correct permissions - Update secret: `npx wrangler secret put API_KEY` --- ### ❌ Cannot create bucket **Symptoms:** - "Failed to create bucket" error - Error about invalid bucket name **Solutions:** 1. **Verify bucket name meets requirements:** - Only lowercase letters (a-z), numbers (0-9), and hyphens (-) - Cannot begin or end with a hyphen - Must be 3-63 characters in length - Examples: - ✅ `my-bucket-123` - ✅ `data-storage` - ❌ `My-Bucket` (uppercase) - ❌ `-invalid` (starts with hyphen) - ❌ `ab` (too short) 2. **Check if bucket name already exists:** ```bash npx wrangler r2 bucket list ``` --- ## Deployment Issues ### ❌ Worker deployment fails **Symptoms:** - `wrangler deploy` command fails - Authentication errors during deploy - Build errors **Solutions:** 1. **Re-authenticate with Cloudflare:** ```bash npx wrangler login ``` 2. **Verify secrets are set:** ```bash npx wrangler secret list ``` Should show: - ACCOUNT_ID - CF_EMAIL - API_KEY - TEAM_DOMAIN - POLICY_AUD 3. **Check build succeeds:** ```bash npm run build ``` If build fails, fix any TypeScript or linting errors. 4. **Verify wrangler.toml syntax:** - Check for typos in configuration - Ensure multiline arrays use proper TOML syntax - Validate binding names match environment 5. **Check API token permissions:** Token needs: - Account → Workers Scripts → Edit - Account → Workers R2 Storage → Edit - Zone → Workers Routes → Edit (if using custom domain) --- ### ❌ Assets not loading after deployment **Symptoms:** - Blank page after deployment - 404 errors for JavaScript/CSS files - "Failed to fetch" errors in console **Solutions:** 1. **Verify build was successful:** ```bash npm run build ``` Check that `dist/` folder contains: - `index.html` - `assets/` folder with JS and CSS files - Favicon and image files 2. **Check ASSETS binding in wrangler.toml:** ```toml # Should be present (automatically configured by Wrangler) # No manual configuration needed for assets ``` 3. **Redeploy with fresh build:** ```bash rm -rf dist npm run build npx wrangler deploy ``` --- ## CORS Errors ### ❌ CORS errors in browser console **Symptoms:** - "CORS policy" error messages - API requests blocked by browser - Preflight OPTIONS requests failing **Solutions:** 1. **Verify Cloudflare Access domain matches Worker domain:** - Access application domain should match deployed Worker domain - Both should use same subdomain/domain 2. **Create Bypass policy for static assets:** - Go to Zero Trust → **Access** → **Applications** → Select your app - Add Bypass policy for: - `/site.webmanifest` - `/favicon.ico` - `/logo.png` - Other static assets 3. **Check API requests include credentials:** In `src/services/api.ts`: ```typescript const response = await fetch(url, { ...options, credentials: "include", // Must be present }); ``` 4. **Verify Worker CORS headers:** Headers should include: ```typescript 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS, PATCH', 'Access-Control-Allow-Headers': 'Content-Type, Authorization, ...' ``` --- ## Upload Issues ### ❌ Upload fails with large files (>100MB) **Symptoms:** - Upload progress bar reaches 100% but fails - "Upload failed" error - Worker returns 413 or 500 error **Solutions:** 1. **Check your Cloudflare plan limits:** - Free/Pro Plans: **100MB maximum** - Business Plan: **200MB maximum** - Enterprise Plan: **500MB maximum** 2. **Upgrade plan if needed:** - Go to [Cloudflare Dashboard](https://dash.cloudflare.com/) - Navigate to **Plans** section - Upgrade to Business or Enterprise for larger uploads 3. **Use chunked uploads:** - Application automatically chunks files >10MB - Ensure chunking logic in `src/services/api.ts` is working - Check Worker receives correct chunk headers 4. **Verify Worker can handle chunk assembly:** - Check Worker logs for chunk processing - Ensure all chunks are received before final upload --- ### ❌ Upload succeeds but file not visible **Symptoms:** - Upload completes successfully - File not shown in file list - Need to refresh page to see file **Solutions:** 1. **Force cache refresh:** - Click refresh icon in UI - Or add `?skipCache=true` to list request 2. **Check file isn't filtered:** - Worker filters out `assets/` folder - Ensure file name doesn't match filter criteria 3. **Verify file list pagination:** - File might be on a different page - Check pagination cursor is correct --- ## Performance Issues ### ❌ Slow bucket operations **Symptoms:** - Bucket rename takes very long - Force delete hangs - Timeout errors **Solutions:** 1. **For large buckets, be patient:** - Bucket operations iterate through all objects - Rate limiting delays are built-in (500ms between batches) - 1000 objects ≈ 5-10 minutes 2. **Check Worker logs:** ```bash npx wrangler tail ``` Look for progress messages showing object processing 3. **For stuck operations:** - Check if Worker is still running - View logs in dashboard: **Workers & Pages** → Select Worker → **Logs** - May need to wait for timeout and retry --- ## Local Development Issues ### ❌ "Port already in use" **Symptoms:** - Cannot start Vite dev server - Cannot start Wrangler dev - EADDRINUSE error **Solutions:** 1. **Kill processes using ports:** ```bash npx kill-port 5173 # Vite npx kill-port 8787 # Wrangler ``` 2. **Or manually find and kill:** ```bash # On macOS/Linux lsof -ti:5173 | xargs kill -9 lsof -ti:8787 | xargs kill -9 # On Windows netstat -ano | findstr :5173 taskkill /PID /F ``` --- ### ❌ Module not found errors **Symptoms:** - Import errors in console - TypeScript errors about missing modules - Build fails with module errors **Solutions:** 1. **Clear and reinstall node_modules:** ```bash rm -rf node_modules package-lock.json npm install ``` 2. **Clear Vite cache:** ```bash rm -rf node_modules/.vite npm run dev ``` 3. **Verify Node.js version:** ```bash node --version # Should be 18+ ``` --- ### ❌ Authentication doesn't work locally **This is expected behavior!** - JWT validation is **disabled** on localhost - All API endpoints are accessible without tokens - This is intentional for easier development **To test with authentication:** 1. Deploy to production and test there, OR 2. Set `.env` to use deployed Worker URL: ``` VITE_WORKER_API=https://your-worker.workers.dev ``` --- ## JWT Token Issues ### ❌ Token validation fails **Symptoms:** - 401 errors despite being logged in - "JWT validation failed" in Worker logs - Token appears in cookies but still unauthorized **Solutions:** 1. **Verify token in jwt.io:** - Copy `cf-access-jwt-assertion` cookie value from DevTools - Paste into [jwt.io](https://jwt.io/) - Check: - `iss` matches your team domain - `aud` contains your Application Audience Tag - `exp` hasn't passed (token not expired) 2. **Check TEAM_DOMAIN format:** ```bash # Must include https:// and full domain npx wrangler secret put TEAM_DOMAIN # Enter: https://yourteam.cloudflareaccess.com ``` 3. **Verify POLICY_AUD:** ```bash npx wrangler secret put POLICY_AUD # Enter: Application Audience Tag from Access dashboard ``` 4. **Enable debug logging:** Add to `worker/index.ts`: ```typescript console.log("[JWT Debug]", { tokenPresent: !!token, issuer: env.TEAM_DOMAIN, audience: env.POLICY_AUD, payload: payload, }); ``` View logs: `npx wrangler tail` --- ## Custom Domain Issues ### ❌ Custom domain not working **Symptoms:** - 404 when accessing custom domain - DNS resolution fails - SSL certificate errors **Solutions:** 1. **Verify domain is on Cloudflare:** - Domain must be managed by Cloudflare - DNS must be proxied (orange cloud) 2. **Check route configuration in wrangler.toml:** ```toml [[routes]] pattern = "r2.yourdomain.com" custom_domain = true ``` 3. **Verify DNS records:** - Go to Cloudflare Dashboard → **DNS** - Should see CNAME or A record for subdomain - Must be proxied (orange cloud icon) 4. **Wait for DNS propagation:** - Can take 5-30 minutes for DNS changes - Use `dig` or `nslookup` to check: ```bash dig r2.yourdomain.com ``` 5. **Check SSL certificate:** - Cloudflare automatically provisions certificates - May take a few minutes after DNS propagation - Check in dashboard: **SSL/TLS** → **Edge Certificates** --- ## Browser-Specific Issues ### ❌ Safari issues with cookies **Symptoms:** - Authentication works in Chrome but not Safari - Cookies not being set in Safari **Solutions:** 1. **Disable "Prevent cross-site tracking":** - Safari → Preferences → Privacy - Uncheck "Prevent cross-site tracking" 2. **Or use Cloudflare Access for Safari:** - This is a Safari privacy feature - Cloudflare Access should handle this automatically - If issues persist, check Access configuration --- ## Rate Limiting Issues ### ❌ "Rate limit exceeded" (429 error) **Symptoms:** - API requests return 429 status code - Error message: "Rate limit exceeded" - Operations fail with "Please wait before retrying" **Solutions:** 1. **Wait before retrying:** - Check the `Retry-After` header in the response - Wait the specified duration (typically 60 seconds) before making more requests - Rate limits reset automatically after the time period 2. **Reduce request frequency:** - Implement client-side caching for frequently accessed data - Use bulk operations where available - Batch multiple operations into fewer API calls 3. **Check which tier is rate limiting:** - Review the `X-RateLimit-Tier` header in the response - **READ** tier: 100 requests per 60 seconds - **WRITE** tier: 30 requests per 60 seconds - **DELETE** tier: 10 requests per 60 seconds 4. **Implement exponential backoff:** ```javascript async function retryWithBackoff(fn, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { return await fn(); } catch (error) { if (error.status === 429 && i < maxRetries - 1) { const retryAfter = error.headers.get("Retry-After") || 60; await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000), ); } else { throw error; } } } } ``` 5. **Check Worker logs for violations:** ```bash npx wrangler tail ``` Look for `[Rate Limit]` entries showing which operations are being rate limited --- ### ❌ Rate limiting not working in production **Symptoms:** - Rate limits not being enforced - No 429 responses when expecting them - Rate limit violations not logged **Solutions:** 1. **Verify rate limiting bindings in wrangler.toml:** ```toml [[ratelimits]] name = "RATE_LIMITER_READ" namespace_id = "1001" simple = { limit = 100, period = 60 } [[ratelimits]] name = "RATE_LIMITER_WRITE" namespace_id = "1002" simple = { limit = 30, period = 60 } [[ratelimits]] name = "RATE_LIMITER_DELETE" namespace_id = "1003" simple = { limit = 10, period = 60 } ``` 2. **Check Wrangler version:** ```bash npx wrangler --version ``` Rate limiting requires Wrangler 4.36.0 or later. Update if necessary: ```bash npm install -D wrangler@latest ``` 3. **Verify deployment succeeded:** ```bash npx wrangler deployments list ``` Ensure the latest deployment includes rate limiting configuration 4. **Check if you're testing from localhost:** - Rate limiting is automatically disabled for `localhost` requests - Test from your deployed production URL instead 5. **Verify Cloudflare Workers plan:** - Rate limiting requires a paid Cloudflare Workers plan ($5/month minimum) - Check your plan at [Cloudflare Dashboard](https://dash.cloudflare.com/) - To upgrade: Dashboard → Workers & Pages → Manage Subscription → Select Paid Plan - Note: All other features work on the free tier --- ### ❌ Different rate limits needed for different users **Symptoms:** - Want higher limits for admin users - Need per-user or per-role rate limits - Current tiered limits are too restrictive/permissive **Solutions:** 1. **Current implementation uses per-user limits:** - All authenticated users have the same rate limits - Limits are enforced independently per user (by email) - One user hitting limits doesn't affect others 2. **To implement custom per-user limits (requires code modification):** Edit `worker/utils/ratelimit.ts`: ```typescript // Define user tiers const ADMIN_USERS = ["admin@example.com"]; const POWER_USERS = ["power@example.com"]; function getRateLimiter(env: Env, tier: RateLimitTier, userEmail: string) { // Give admins higher limits if (ADMIN_USERS.includes(userEmail)) { switch (tier) { case "READ": return { limiter: env.RATE_LIMITER_READ, limit: 500, period: 60 }; case "WRITE": return { limiter: env.RATE_LIMITER_WRITE, limit: 150, period: 60 }; case "DELETE": return { limiter: env.RATE_LIMITER_DELETE, limit: 50, period: 60 }; } } // Use default limits return getRateLimiter(env, tier); } ``` 3. **To adjust global rate limits:** Edit limits in `wrangler.toml`: ```toml [[ratelimits]] name = "RATE_LIMITER_READ" namespace_id = "1001" simple = { limit = 200, period = 60 } # Increased from 100 ``` Then redeploy: ```bash npx wrangler deploy ``` --- ### ❌ Rate limit violations being logged excessively **Symptoms:** - Worker logs filled with rate limit violations - Too many `[Rate Limit]` entries - Difficult to find other log messages **Solutions:** 1. **This is expected behavior:** - All rate limit violations are logged for security monitoring - Helps identify potential abuse or misconfigured clients 2. **To reduce violations:** - Implement proper retry logic in your API client - Add client-side request throttling - Use caching to reduce redundant API calls 3. **To filter logs:** ```bash # View only non-rate-limit logs npx wrangler tail | grep -v "Rate Limit" # View only rate limit violations npx wrangler tail | grep "Rate Limit" ``` 4. **To disable violation logging (not recommended):** Edit `worker/utils/ratelimit.ts` and comment out the logging: ```typescript if (!success) { // console.warn('[Rate Limit] Limit exceeded', { ... }); } ``` --- ## Getting Help If you're still experiencing issues: 1. **Check Worker logs:** ```bash npx wrangler tail ``` 2. **Enable debug mode:** - Add verbose logging to Worker - Check browser console for errors - Review Network tab in DevTools 3. **Search GitHub Issues:** - Check [existing issues](https://github.com/neverinfamous/R2-Manager-Worker/issues) - Someone may have already solved your problem 4. **Open a new issue:** - Visit [GitHub Issues](https://github.com/neverinfamous/R2-Manager-Worker/issues/new) - Include: - Clear description of the problem - Steps to reproduce - Error messages and logs - Browser and OS information - Screenshots if relevant 5. **Ask in Discussions:** - Visit [GitHub Discussions](https://github.com/neverinfamous/R2-Manager-Worker/discussions) - For questions and general help --- ## Additional Resources - [Cloudflare Workers Troubleshooting](https://developers.cloudflare.com/workers/observability/troubleshooting/) - [Cloudflare R2 Troubleshooting](https://developers.cloudflare.com/r2/troubleshooting/) - [Cloudflare Access Troubleshooting](https://developers.cloudflare.com/cloudflare-one/faq/teams-troubleshooting/) - [Wrangler CLI Troubleshooting](https://developers.cloudflare.com/workers/wrangler/troubleshooting/)