Downloadbypass
A lightweight client-side helper that prompts players to download missing, external mod dependencies on first launch and installs them into the mods/ folder. It is designed for modpacks and servers that want a smoother onboarding experience without bundling third-party jars directly.
This page explains what the mod does, how the download flow works, and how to configure it using config/external-mods.json.
What it does
- Prompts the player in-game when required mods are missing.
- Downloads missing mods from multiple trusted sources:
- CurseForge REST API (preferred if an API key is present) or Curse Maven fallback
- GitHub Releases (public or private with token)
- GitLab Releases (GitLab.com or self-hosted instances)
- Modrinth (modern mod hosting platform)
- Maven Repositories (Maven Central, Forge Maven, Fabric Maven, JitPack, custom repos)
- Direct URLs (any HTTP/HTTPS download link with redirect support)
- Verifies downloaded files by size and/or checksum before installing.
- Installs the verified jars into the standard
mods/folder. - Remembers what it installed and offers a one-click cleanup button to remove auto-installed mods.
- Skip tracking: If you decline an optional mod, it won't prompt again for 7 days.
Note: This mod is client-only. Mods are only loaded on the next game start after install.
How it works (high level)
- On client setup,
Downloadbypasschecksconfig/external-mods.jsonfor a list of external dependencies. - For each dependency that is not already installed, the player sees a confirmation prompt that shows the mod name and reason.
- On approval, the mod resolves a download URL from the configured source (CurseForge, GitHub, GitLab, Modrinth, Maven, or direct URL) and downloads to a temporary
*.partfile. - Downloads support HTTP Range requests for automatic resume if interrupted.
- After the download finishes and verification succeeds, the file is atomically moved to
mods/<filename>.jar. - If any required dependency fails or is declined, the game exits with a helpful message.
- Optional mods that are declined are tracked and won't prompt again for 7 days.
Why a mod like this?
- Avoid shipping third-party jars in your distribution, while still guiding players to the correct files.
- Ensure the exact intended artifact (file) is installed, matching the loader and game version you target.
Configuration file: config/external-mods.json
- Location:
config/external-mods.json(relative to the game directory). - Format: JSON with a schema version and a
modsarray. - Schema version currently supported:
"1.0".
Minimal example
{
"schema_version": "1.0",
"mods": [
{
"name": "Example Mod",
"slug": "example-mod",
"curseforge_id": 123456,
"file_id": 5678901,
"version": "mc1.20.1",
"required": true,
"reason": "Required core library for the pack"
}
]
}
Examples for all download sources
{
"schema_version": "1.0",
"mods": [
{
"name": "CurseForge Mod",
"slug": "fancy-structures",
"curseforge_id": 412345,
"file_id": 4876543,
"version": "1.20.1-forge",
"required": true,
"reason": "Provides worldgen used by the pack",
"size_bytes": 3827465,
"sha256_hash": "9b7f03da9c935e6e...<trimmed>...a3f2"
},
{
"name": "GitHub Release Mod",
"source": "github",
"github_owner": "username",
"github_repo": "my-mod",
"github_tag": "v1.0.0",
"github_asset_pattern": ".*-forge\\.jar$",
"version": "1.20.1",
"required": false,
"sha256_hash": "abc123..."
},
{
"name": "GitLab Mod",
"source": "gitlab",
"gitlab_host": "gitlab.com",
"gitlab_project": "team/awesome-mod",
"gitlab_tag": "v2.0.0",
"version": "1.20.1",
"required": false
},
{
"name": "Modrinth Mod",
"source": "modrinth",
"modrinth_project_id": "AANobbMI",
"modrinth_loader": "forge",
"version": "1.20.1",
"required": false,
"reason": "Performance enhancement"
},
{
"name": "Maven Artifact",
"source": "maven",
"maven_repository": "https://maven.minecraftforge.net/",
"maven_group_id": "net.minecraftforge",
"maven_artifact_id": "forge",
"maven_version": "1.20.1-47.2.0",
"maven_classifier": "universal",
"required": true
},
{
"name": "Direct Download",
"source": "direct_url",
"download_url": "https://example.com/mods/custom-mod.jar",
"version": "1.20.1",
"sha256_hash": "def456...",
"required": false
}
]
}
Fields (per mod entry)
name(string)- Human-readable mod name. Displayed in the in-game prompt.
slug(string)- CurseForge project slug. Also used to build the Curse Maven artifact path.
curseforge_id(integer)- CurseForge project ID (numeric). Required for resolution.
file_id(integer)- CurseForge file ID (numeric) that exactly identifies the intended artifact build.
- Critical to select the correct loader (Forge) and game version (e.g., 1.20.1).
version(string)- Free-form informational string shown in logs. Commonly includes the Minecraft version.
- The mod logs a warning if it doesn’t appear to match the current game version, but does not block installation.
required(boolean)- If true, the game will exit if the player declines install or if installation fails.
reason(string)- Short explanation shown to the player describing why the mod is needed.
size_bytes(integer, optional)- Expected file size used for a quick verification pass.
sha256_hash(string, optional)- Preferred cryptographic checksum verification. Use lowercase hex without delimiters.
md5_hash(string, optional)- Fallback checksum verification if SHA-256 is not provided.
Choosing the correct file_id
- On the CurseForge project page, each file has:
- A specific loader (Forge/Fabric/Quilt) and a game version tag (e.g., 1.20.1).
- Always pick the Forge file for the exact game version you target.
- Copy the numeric File ID from that file’s page and paste it as
file_id.
If you accidentally point to a Fabric/Quilt file or a different Minecraft version, a startup crash is likely. Typical stack traces contain NoSuchFieldError or failed mixin injections involving vanilla classes.
Download sources and selection
- If the environment variable
CURSEFORGE_API_KEYis present, the mod prefers the CurseForge REST API to resolve the file’s metadata and download URL. - Without an API key, it tries known Curse Maven bases using the canonical path format:
https://www.cursemaven.com/curse/maven/<slug>-<projectId>/<fileId>/<slug>-<projectId>-<fileId>.jar
- If Maven lookup fails or the project disallows third-party distribution, the mod falls back to the CurseForge API (some information may still be available without a key).
Respect project distribution policies and API rate limits. If a project prohibits third‑party hosting, Curse Maven will not serve the file.
Verification and safety
- The download is written to a temporary
*.partfile. - Resume support: If download is interrupted, it will automatically resume from where it left off using HTTP Range requests (server support required).
- After the transfer completes, the file is moved atomically to
mods/<final>.jar(same volume), minimizing the chance of partial installs. - Verification stages:
- Optional size check if
size_bytesis provided. - Checksum verification (SHA‑256 preferred, MD5 as fallback) if provided.
- Optional size check if
- If verification fails, the temporary file is removed, and the install is aborted.
- Download caching: API responses are cached for 5 minutes to reduce repeated API calls.
- Skip tracking: Declined optional mods are tracked for 7 days to avoid repeated prompts.
Mods are only picked up on the next game start. Installing during runtime does not affect the current session.
Security proxy and VirusTotal scanning
Downloadbypass now uses a mandatory secure proxy to gate all external downloads through a Supabase Edge Function with VirusTotal scanning.
- Architecture
- Client requests a signed URL via Supabase Edge Function
request-downloadusing a hardcoded project endpoint. - The function fetches the file server-side, computes
sha256, checks a server blocklist, uploads to Supabase Storage, and records metadata. - VirusTotal flow:
- First tries a VT hash lookup by
sha256. - If found: evaluates against tolerance and returns a decision.
- If not found: uploads the file to VT for analysis, inserts a
scansrow, and returnspending. The client then pollsdownload-statusuntil a final decision.
- First tries a VT hash lookup by
- Client requests a signed URL via Supabase Edge Function
- Tolerance rules
- Sources from CurseForge/Modrinth domains allow up to 1 positive on VirusTotal.
- All other sources require 0 positives.
- Decisions and fields
- Server responses include:
status(ready/blocked/pending),decision,message,vt_positives,vt_total,vt_tolerance, andvt_report_url. - When approved, the response also includes a short-lived
download_url(signed URL) andsize.
- Server responses include:
- Mandatory proxy
- There is no direct-download fallback. If the proxy blocks or times out:
- Required mods stop the game with a clear message.
- Optional mods are skipped for this session.
- There is no direct-download fallback. If the proxy blocks or times out:
- UI improvements
- The in-game prompt shows VirusTotal status, e.g.
Security passed: VirusTotal 0/70 (tol 1). - When blocked, the prompt shows a descriptive reason including VT counts and offers a button to open the VirusTotal report.
- The in-game prompt shows VirusTotal status, e.g.
- Configuration
- Client side does not need any environment variables for the proxy; the Supabase project endpoint is hardcoded and the proxy is always on.
- Server side requires standard Supabase keys and a
VIRUSTOTAL_API_KEYto enable scanning.
Player experience
- On first launch, if dependencies are missing:
- A prompt appears per mod with its name and reason.
- A progress indicator shows download progress.
- On success, the player is reminded to restart to load the new mods.
- A secondary action allows removing all auto-installed jars if the player changes their mind.
Compatibility notes
- Loader: Forge (client). The files you reference must be Forge builds.
- Game version: Use file IDs that match the exact Minecraft version you support (e.g., 1.20.1).
- If you see boot errors like
NoSuchFieldErroron vanilla classes, you likely selected the wrong loader or game version file ID.
Troubleshooting
The prompt never appears
- Ensure
config/external-mods.jsonexists and hasschema_versionset to"1.0". - Confirm there are entries in
mods[]. - Check if mod was previously declined (skip tracking). Delete
config/downloadbypass/skipped-mods.jsonto reset.
Download fails immediately
- Network connectivity: Check internet connection
- Rate limiting: Set appropriate environment variables (
GITHUB_TOKEN,GITLAB_TOKEN,CURSEFORGE_API_KEY) - Private repos: Ensure tokens have correct permissions
- Third-party distribution: Some CurseForge projects disallow third-party hosting
- Check logs for
[EXTERNAL-MODS]messages with HTTP status codes
GitHub/GitLab specific issues
- 404 Not Found: Verify repository path, release tag, or asset name pattern
- 401/403 Unauthorized: Set
GITHUB_TOKENorGITLAB_TOKENenvironment variable - No matching asset: Check
github_asset_patternorgitlab_asset_patternregex
Modrinth issues
- No versions found: Check if mod supports your Minecraft version and loader
- Verify
modrinth_loadermatches your modpack (forge/fabric/neoforge)
Maven issues
- Artifact not found: Verify Maven coordinates (group, artifact, version)
- Check repository URL is correct and accessible
- Try accessing the artifact URL directly in a browser
Startup crash after installing
- Verify the installed jar is a Forge mod for the correct game version.
- Open the jar as a zip. Forge mods typically contain
META-INF/mods.toml. Fabric/Quilt mods containfabric.mod.jsonorquilt.mod.json. - Check
github_asset_pattern,modrinth_loader, ormaven_classifierto ensure you're getting the Forge version
Verification fails
- Ensure
size_bytesor hashes match the actual file - For GitHub/GitLab, asset may have changed - verify hash with actual download
- Remove the incorrect jar and restart to retry
Resume not working
- Server must support HTTP Range requests (most do)
- Check logs for "Resuming download from X bytes"
- If server doesn't support resume, download will restart automatically
Best practices for pack authors
- Always pin exact versions:
- CurseForge: Use
file_idfor exact Forge+MC version - GitHub/GitLab: Use
github_tag/gitlab_taginstead of latest - Modrinth: Use
modrinth_version_idfor specific versions - Maven: Use exact
maven_versionstrings
- CurseForge: Use
- Always provide
sha256_hashfor integrity verification. - Keep
requiredtotrueonly for hard requirements. - Write clear
reasonmessages so players understand why each dependency is needed. - Use
sourcefield explicitly to avoid auto-detection ambiguity. - Test with all sources in a clean instance before release.
- For private mods, provide documentation on setting environment variables (
GITHUB_TOKEN,GITLAB_TOKEN). - Consider using Maven repositories for internal/company mods for better reliability.
- Use Modrinth when possible for modern mods (better API, no rate limiting).
Environment variables
All environment variables are optional but recommended for better rate limits and reliability:
-
CURSEFORGE_API_KEY- Enables CurseForge API-first resolution
- Improves reliability and speed for CurseForge downloads
-
GITHUB_TOKEN- GitHub personal access token
- Increases rate limit from 60 to 5000 requests/hour
- Required for private repositories
-
GITLAB_TOKEN- GitLab private access token
- Enables access to private projects
- Increases rate limits on self-hosted instances
Do not hardcode keys into public packs. Use documentation to instruct players/launchers to supply keys if needed.

