{"record":{"id":"8bdef5bd6e68fb97","repo":"agalwood/Motrix","slug":"geoipdatabaseinvalid","errorCode":"GeoIPDatabaseInvalid","errorMessage":"database too small (${buffer.length} bytes)","messagePattern":"database too small \\((.+?) bytes\\)","errorType":"error_code","errorClass":"AppError","httpStatus":null,"severity":"error","filePath":"src/core/geoip/geo-ip-downloader.ts","lineNumber":128,"sourceCode":"      }\n\n      const reader = body.getReader()\n      while (true) {\n        const { value, done } = await reader.read()\n        if (done) break\n        if (value) {\n          chunks.push(value)\n          bytesReceived += value.byteLength\n          emit(false)\n        }\n      }\n    } finally {\n      clearTimeout(timeoutId)\n    }\n\n    const buffer = Buffer.concat(chunks)\n    if (buffer.length < MIN_VALID_SIZE_BYTES) {\n      throw new AppError(\n        ErrorCode.GeoIPDatabaseInvalid,\n        `database too small (${buffer.length} bytes)`\n      )\n    }\n    if (!hasMmdbSentinel(buffer)) {\n      throw new AppError(\n        ErrorCode.GeoIPDatabaseInvalid,\n        'MaxMind.com metadata marker not found — file is not a valid .mmdb'\n      )\n    }\n\n    try {\n      // writeFileAtomic handles fsync + rename + tmp cleanup on\n      // failure, so we no longer need an explicit unlink in the\n      // catch path.\n      await writeFileAtomic(dbPath, buffer)\n    } catch (err) {\n      throw new AppError(","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/geoip/geo-ip-downloader.ts#L110-L146","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nconst buffer = Buffer.concat(chunks)\nif (buffer.length < MIN_VALID_SIZE_BYTES) {\n  throw new AppError(ErrorCode.GeoIPDatabaseInvalid, `database too small (${buffer.length} bytes)`)\n}\n\n// after — reject early when the server itself reports an undersized body\nif (bytesTotal > 0 && bytesTotal < MIN_VALID_SIZE_BYTES) {\n  throw new AppError(ErrorCode.GeoIPDatabaseInvalid, `server reports only ${bytesTotal} bytes`)\n}\nconst buffer = Buffer.concat(chunks)\nif (buffer.length < MIN_VALID_SIZE_BYTES) {\n  throw new AppError(ErrorCode.GeoIPDatabaseInvalid, `database too small (${buffer.length} bytes)`)\n}","handlingStrategy":"validation","validationCode":"// Use the server's content-length to reject undersized payloads early.\nconst total = Number.parseInt(response.headers.get('content-length') ?? '', 10)\nif (Number.isFinite(total) && total > 0 && total < MIN_VALID_SIZE_BYTES) {\n  throw new AppError(ErrorCode.GeoIPDatabaseInvalid, `server reports only ${total} bytes; aborting download`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  await downloader.download(url)\n} catch (err) {\n  if (err instanceof AppError && err.code === ErrorCode.GeoIPDatabaseInvalid && /too small/.test(err.message)) {\n    // re-fetch from a known-good mirror or report bad source URL\n  } else throw err\n}","preventionTips":["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."],"tags":["geoip","validation","download","integrity"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}