lionsoul2014/ip2region · error

invalid version `%d`

Error message

invalid version `%d`

What it means

VersionFromHeader inspects the xdb file header to decide the IP version. Old (2.0) structures are IPv4-only; new (3.0) headers carry an explicit IP version. If header.Version is neither Structure20 nor Structure30, the header is corrupt or from an unknown format and this error is thrown with the raw version number.

Source

Thrown at binding/golang/xdb/version.go:100

	switch strings.ToUpper(name) {
	case "V4", "IPV4":
		return IPv4, nil
	case "V6", "IPV6":
		return IPv6, nil
	default:
		return IPvx, fmt.Errorf("invalid version name `%s`", name)
	}
}

func VersionFromHeader(header *Header) (*Version, error) {
	// old structure with IPv4 supports ONLY
	if header.Version == Structure20 {
		return IPv4, nil
	}

	// structure 3.0 after IPv6 supporting
	if header.Version != Structure30 {
		return IPvx, fmt.Errorf("invalid version `%d`", header.Version)
	}

	switch header.IPVersion {
	case IPv4VersionNo:
		return IPv4, nil
	case IPv6VersionNo:
		return IPv6, nil
	default:
		return IPvx, fmt.Errorf("invalid version `%d`", header.IPVersion)
	}
}

View on GitHub (pinned to c1a1fc7d59)

Solutions

  1. Re-download/re-export the xdb file and verify its size and checksum against the publisher
  2. Verify the file starts with a valid xdb header (check the first bytes / try Header verification tooling)
  3. Ensure the file was generated with a compatible maker version (structure 2.0 or 3.0)
  4. Confirm the path points to the xdb data file, not an index or config file

Example fix

// before
v, err := xdb.VersionFromHeader(hdr) // hdr.Version == 0 (truncated file)
// after
fi, _ := os.Stat(xdbPath)
if fi == nil || fi.Size() < 256 { return fmt.Errorf("xdb too small/corrupt: %s", xdbPath) }
v, err := xdb.VersionFromHeader(hdr)
Defensive patterns

Strategy: validation

Validate before calling

fi, err := os.Stat(xdbPath)
if err != nil || fi.Size() < 256 { return fmt.Errorf("xdb missing or truncated: %s", xdbPath) }

Type guard

func looksLikeXDB(b []byte) bool { return len(b) >= 256 }
// then: v, err := xdb.VersionFromHeader(hdr); usable if err == nil

Try / catch

hdr, err := xdb.LoadHeaderFromFile(xdbPath)
if err != nil { return fmt.Errorf("cannot read xdb header %s: %w", xdbPath, err) }
v, err := xdb.VersionFromHeader(hdr)
if err != nil { return fmt.Errorf("unsupported xdb %s: %w", xdbPath, err) }

Prevention

When it happens

Trigger: Calling VersionFromHeader (directly or via NewSearcher/newConfig) on a file whose 256-byte header was truncated, corrupted in transfer, or written by an unrecognized writer version; or pointing the searcher at a non-xdb file.

Common situations: Partial uploads/FTP transfers in ASCII mode corrupting the header, downloading an HTML error page saved as .xdb, opening an unrelated binary renamed to .xdb, or a file produced by a newer incompatibly-versioned maker.

Related errors


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