crowdsecurity/crowdsec · error

unable to parse jwt expiration: %w

Error message

unable to parse jwt expiration: %w

What it means

The CAPI authentication succeeded but the token expiration timestamp returned in authResp.Expire could not be parsed into a time.Time via transport.Expiration.UnmarshalText. The Central API returned a missing or malformed expiry string, so the client cannot know when to re-authenticate.

Source

Thrown at pkg/apiserver/apic.go:285

	scenarios, err := a.FetchScenariosListFromDB(ctx)
	if err != nil {
		return fmt.Errorf("get scenario in db: %w", err)
	}

	password := strfmt.Password(config.Credentials.Password)

	authResp, _, err := a.apiClient.Auth.AuthenticateWatcher(ctx, models.WatcherAuthRequest{
		MachineID: &config.Credentials.Login,
		Password:  &password,
		Scenarios: scenarios,
	})
	if err != nil {
		return fmt.Errorf("authenticate watcher (%s): %w", config.Credentials.Login, err)
	}

	if err = transport.Expiration.UnmarshalText([]byte(authResp.Expire)); err != nil {
		return fmt.Errorf("unable to parse jwt expiration: %w", err)
	}

	transport.Token = authResp.Token

	return a.dbClient.SaveAPICToken(ctx, authResp.Token)
}

// keep track of all alerts in cache and push it to CAPI every PushInterval.
func (a *apic) Push(ctx context.Context) error {
	var cache modelscapi.AddSignalsRequest

	ticker := time.NewTicker(a.pushIntervalFirst)

	log.Infof("Start push to CrowdSec Central API (interval: %s once, then %s)", a.pushIntervalFirst.Round(time.Second), a.pushInterval)

	for {
		select {
		case <-a.pushTomb.Dying(): // if one apic routine is dying, do we kill the others?

View on GitHub (pinned to 909b515798)

Solutions

  1. Retry — a malformed Expire field from CAPI is often transient and fixed by a fresh authentication round
  2. Upgrade crowdsec: newer releases tolerate more expiry formats
  3. If persistent, capture the raw auth response and report it — it indicates a Central API contract change
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at pkg/apiserver/apic.go:285 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/fac8d7d7599fe7f2. Report an issue: GitHub.