agalwood/Motrix · error · AppError
GeoIPDatabaseInvalid
GeoIPDatabaseInvalid
Error message
database too small (${buffer.length} bytes) What it means
Thrown after the full download is buffered: if Buffer.concat(chunks).length is below MIN_VALID_SIZE_BYTES, the file is too small to be a real GeoIP database and is rejected as GeoIPDatabaseInvalid. This catches truncated/error-page downloads that nevertheless returned HTTP 200.
Source
Thrown at src/core/geoip/geo-ip-downloader.ts:128
}
const reader = body.getReader()
while (true) {
const { value, done } = await reader.read()
if (done) break
if (value) {
chunks.push(value)
bytesReceived += value.byteLength
emit(false)
}
}
} finally {
clearTimeout(timeoutId)
}
const buffer = Buffer.concat(chunks)
if (buffer.length < MIN_VALID_SIZE_BYTES) {
throw new AppError(
ErrorCode.GeoIPDatabaseInvalid,
`database too small (${buffer.length} bytes)`
)
}
if (!hasMmdbSentinel(buffer)) {
throw new AppError(
ErrorCode.GeoIPDatabaseInvalid,
'MaxMind.com metadata marker not found — file is not a valid .mmdb'
)
}
try {
// writeFileAtomic handles fsync + rename + tmp cleanup on
// failure, so we no longer need an explicit unlink in the
// catch path.
await writeFileAtomic(dbPath, buffer)
} catch (err) {
throw new AppError(View on GitHub (pinned to 1a708ee577)
Solutions
- Open the downloaded URL in a browser to confirm it actually serves the full database.
- Check content-length against MIN_VALID_SIZE_BYTES in the response headers before trusting the body.
- Retry — partial delivery is often transient.
- Point the source URL at the canonical full database archive.
- Inspect network/proxy MTU or compression settings that may truncate the body.
Example fix
// before
const buffer = Buffer.concat(chunks)
if (buffer.length < MIN_VALID_SIZE_BYTES) {
throw new AppError(ErrorCode.GeoIPDatabaseInvalid, `database too small (${buffer.length} bytes)`)
}
// after — reject early when the server itself reports an undersized body
if (bytesTotal > 0 && bytesTotal < MIN_VALID_SIZE_BYTES) {
throw new AppError(ErrorCode.GeoIPDatabaseInvalid, `server reports only ${bytesTotal} bytes`)
}
const buffer = Buffer.concat(chunks)
if (buffer.length < MIN_VALID_SIZE_BYTES) {
throw new AppError(ErrorCode.GeoIPDatabaseInvalid, `database too small (${buffer.length} bytes)`)
} Defensive patterns
Strategy: validation
Validate before calling
// Use the server's content-length to reject undersized payloads early.
const total = Number.parseInt(response.headers.get('content-length') ?? '', 10)
if (Number.isFinite(total) && total > 0 && total < MIN_VALID_SIZE_BYTES) {
throw new AppError(ErrorCode.GeoIPDatabaseInvalid, `server reports only ${total} bytes; aborting download`)
} Try / catch
try {
await downloader.download(url)
} catch (err) {
if (err instanceof AppError && err.code === ErrorCode.GeoIPDatabaseInvalid && /too small/.test(err.message)) {
// re-fetch from a known-good mirror or report bad source URL
} else throw err
} Prevention
- Point the source URL at the canonical full database archive.
- Check content-length against MIN_VALID_SIZE_BYTES before consuming the body.
- Retry once on suspiciously small payloads.
- Inspect any proxy that may truncate responses.
When it happens
Trigger: buffer.length < MIN_VALID_SIZE_BYTES. The server returned a small payload (truncated file, a short HTML error page with 200, a redirect-stub, or a partial read due to early disconnect).
Common situations: Upstream CDN served a stub/error page with status 200; connection dropped mid-download but a tiny body was captured; the configured URL points to a metadata file rather than the database; an aggressive proxy truncated the response.
Related errors
- GeoIPDownloadFailed
- invalid-url-scheme
- invalid Chrome extension ID: ${id}
- invalid Firefox extension ID: ${id}
- aria2 addTorrent gid must contain exactly 16 hexadecimal cha
AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12).
Data as JSON: /api/errors/8bdef5bd6e68fb97.
Report an issue: GitHub.