XTLS/Xray-core · error · errors.Error

invalid geodata cron

Error message

invalid geodata cron

What it means

Returned when the robfig/cron parser rejects the configured geodata update schedule (config.Cron) passed to g.tasker.AddFunc. The cron library's parse error is chained as the Base cause.

Source

Thrown at app/geodata/geodata.go:48

		assets: config.Assets,
	}

	if len(g.assets) > 0 {
		var dispatcher routing.Dispatcher
		if err := core.RequireFeatures(ctx, func(d routing.Dispatcher) {
			dispatcher = d
		}); err != nil {
			return nil, errors.New("failed to get dispatcher for geodata downloader").Base(err)
		}
		g.downloader = newDownloader(ctx, dispatcher, config.Outbound)
	}

	g.tasker = cron.New(
		cron.WithChain(cron.SkipIfStillRunning(cron.DiscardLogger)),
		cron.WithLogger(cron.DiscardLogger),
	)
	if _, err := g.tasker.AddFunc(config.Cron, g.execute); err != nil {
		return nil, errors.New("invalid geodata cron").Base(err)
	}
	errors.LogInfo(ctx, "scheduled geodata reload with cron: ", config.Cron)

	return g, nil
}

func (g *Instance) execute() {
	var err error
	if g.downloader != nil {
		err = g.reloadWithUpdate()
	} else {
		err = reload()
	}
	if err != nil {
		errors.LogErrorInner(context.Background(), err, "scheduled geodata reload failed")
	}
}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Use a standard 5-field cron expression, e.g. '30 4 * * *' for 04:30 daily
  2. Read the chained Base error from the cron parser — it pinpoints the offending field
  3. Validate the expression with an online cron parser or robfig/cron's parser in a scratch program before shipping config

Example fix

// before (xray config json)
"geodata": { "cron": "every 2 hours" } // invalid
// after
"geodata": { "cron": "0 */2 * * *" } // valid 5-field cron
Defensive patterns

Strategy: validation

Validate before calling

// Validate the cron expression with the same parser the app uses:
import "github.com/robfig/cron/v3"

parser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow)
if _, err := parser.Parse(config.Cron); err != nil {
    return fmt.Errorf("bad geodata cron %q: %w", config.Cron, err)
}

Prevention

When it happens

Trigger: Setting geodata.updateCron/cron in the Xray config to a string that is not a valid cron expression — wrong field count, bad ranges like '70 * * * *', unsupported macros, or stray characters.

Common situations: Using 6-field or 7-field cron strings when the parser expects 5; typos such as '*/2 hourse * * *'; assuming systemd-timer or crontab shorthand syntax that robfig/cron v3 does not accept by default.

Related errors


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