lionsoul2014/ip2region · error

loading header: %w

Error message

loading header: %w

What it means

Verify validates an xdb file handle and starts by loading the file's header via LoadHeader; if that read/parse fails, the underlying error is wrapped as "loading header". This typically indicates the file is too small, unreadable, or not an xdb file at all.

Source

Thrown at binding/golang/xdb/util.go:147

func IPMiddle(sip, eip []byte) ([]byte, error) {
	buf, err := IPAdd(sip, eip)
	if err != nil {
		return []byte{}, fmt.Errorf("IPSub(%s, %s): %w", IP2String(sip), IP2String(eip), err)
	}

	return IPHalf(buf), nil
}

// Verify if the current Searcher could be used to search the specified xdb file.
// Why do we need this check ?
// The future features of the xdb impl may cause the current searcher not able to work properly.
//
// @Note: You Just need to check this ONCE when the service starts
// Or use another process (eg, A command) to check once Just to confirm the suitability.
func Verify(handle *os.File) error {
	header, err := LoadHeader(handle)
	if err != nil {
		return fmt.Errorf("loading header: %w", err)
	}

	// get the runtime ptr bytes
	runtimePtrBytes := 0
	switch header.Version {
	case Structure20:
		runtimePtrBytes = 4
	case Structure30:
		runtimePtrBytes = header.RuntimePtrBytes
	default:
		return fmt.Errorf("invalid version: %d", header.Version)
	}

	// 1, confirm the xdb file size.
	// to sure that the MaxFilePointer does no overflow
	stat, err := handle.Stat()
	if err != nil {
		return fmt.Errorf("file stat: %w", err)

View on GitHub (pinned to c1a1fc7d59)

Solutions

  1. Check the file exists, is a regular file, and is readable by the current user
  2. Re-download the xdb file and confirm its size/checksum
  3. Ensure the handle is opened successfully and not closed before Verify
  4. Confirm the file is actually an xdb v2/v3 data file, not HTML from a failed download

Example fix

// before
f, _ := os.Open("bad.xdb")
err := xdb.Verify(f) // loading header: ...
// after
stat, err := os.Stat("bad.xdb")
if err != nil || stat.Size() < 256 { log.Fatal("xdb missing or truncated") }
err = xdb.VerifyFromFile("bad.xdb")
Defensive patterns

Strategy: validation

Validate before calling

func xdbReadable(path string) error {
    info, err := os.Stat(path)
    if err != nil { return err }
    if !info.Mode().IsRegular() { return fmt.Errorf("%s is not a regular file", path) }
    if info.Size() < 256 { return fmt.Errorf("%s too small (%d bytes) to be an xdb file", path, info.Size()) }
    f, err := os.Open(path)
    if err != nil { return err }
    defer f.Close()
    return nil
}

Try / catch

if err := xdb.VerifyFromFile(dbPath); err != nil {
    return fmt.Errorf("xdb %s failed verification: %w", dbPath, err)
}

Prevention

When it happens

Trigger: Calling xdb.Verify(handle) or VerifyFromFile on a file smaller than the header, with wrong permissions, an empty file, or a random/corrupted file; passing a closed *os.File.

Common situations: Pointing the tool at a wrong path that resolved to a directory or empty placeholder; partially downloaded xdb; file corrupted in transit; running the check as a user lacking read permission.

Related errors


AI-assisted analysis of lionsoul2014/ip2region@c1a1fc7d59 (2026-09-02). Data as JSON: /api/errors/f0ba1483c9e65179. Report an issue: GitHub.