XTLS/Xray-core · error

invalid geodata cron

Error message

invalid geodata cron

What it means

Thrown by GeodataConfig.Build when the optional geodata cron expression fails robfig/cron's ParseStandard. The cron field schedules automatic geodata asset updates; it must be a valid standard 5-field cron expression (with optional @every-style support per ParseStandard). The parse error is attached as the base cause.

Source

Thrown at infra/conf/geodata.go:53

	}
	if u.Scheme != "https" || u.Host == "" {
		return errors.New("scheme must be https")
	}
	return nil
}

type GeodataConfig struct {
	Cron     *string               `json:"cron"`
	Outbound string                `json:"outbound"`
	Assets   []*GeodataAssetConfig `json:"assets"`
}

func (c *GeodataConfig) Build() (proto.Message, error) {
	config := &geodata.Config{}

	if c.Cron != nil {
		if _, err := cron.ParseStandard(*c.Cron); err != nil {
			return nil, errors.New("invalid geodata cron").Base(err)
		}
		config.Cron = *c.Cron
	}

	config.Outbound = c.Outbound

	assets := make([]*geodata.Asset, 0, len(c.Assets))
	for _, asset := range c.Assets {
		built, err := asset.Build()
		if err != nil {
			return nil, err
		}
		assets = append(assets, built)
	}
	config.Assets = assets

	return config, nil
}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Use a standard 5-field cron expression, e.g. "0 4 * * *" for 04:00 daily
  2. Use the @every form with a valid duration, e.g. "@every 12h"
  3. Read the chained base error, which names the exact field or token cron rejected

Example fix

// before
"cron": "every 1h"
// after
"cron": "@every 1h"
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := cron.ParseStandard(cfg.Cron); err != nil {
	return fmt.Errorf("bad cron %q: %w", cfg.Cron, err)
}

Try / catch

// Go: pre-validate cron before config build
if c.Cron != nil {
	if _, err := cron.ParseStandard(*c.Cron); err != nil {
		// surface early with config context instead of failing inside Build
		return fmt.Errorf("geodata.cron invalid: %w", err)
	}
}

Prevention

When it happens

Trigger: Setting the geodata block's cron to a malformed expression such as "* * *" (too few fields), "61 * * * *" (out-of-range minute), or "every 1h" (not a recognized @every duration).

Common situations: Copy-paste of 6-field Quartz-style cron from Java tooling; assuming natural-language schedules work; typos in @every durations like "@every 1 d".

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/210220f32e1da37b. Report an issue: GitHub.