crowdsecurity/crowdsec · error

unable to parse token

Error message

unable to parse token

What it means

LoadAPICToken parses the stored JWT without signature verification (ParseUnverified) to read claims. ErrTokenParse is returned when the raw string is not parseable as a JWT, or when the parsed token's claims don't hold jwt.MapClaims. It is always wrapped with the underlying parse error when available.

Source

Thrown at pkg/database/token.go:17

package database

import (
	"context"
	"errors"
	"fmt"
	"time"

	"github.com/golang-jwt/jwt/v4"
	"github.com/sirupsen/logrus"
)

const APICTokenKey = "apic_token"

var (
	ErrTokenNotFound     = errors.New("token not found in DB")
	ErrTokenParse        = errors.New("unable to parse token")
	ErrTokenMissingClaim = errors.New("token missing required claim")
	ErrTokenExpired      = errors.New("token expired")
)

type APICToken struct {
	Raw       string
	ExpiresAt time.Time
}

// LoadAPICToken attempts to retrieve and validate a JWT token from the local database.
// Errors are returned if the token can't be read, is not valid, expired or has no expiration.
func (c *Client) LoadAPICToken(ctx context.Context, logger logrus.FieldLogger) (APICToken, error) {
	token, err := c.GetConfigItem(ctx, APICTokenKey) // TokenKey is a constant string representing the key for the token in the database
	if err != nil {
		return APICToken{}, fmt.Errorf("loading token: %w", err)
	}

	if token == "" {

View on GitHub (pinned to 909b515798)

Solutions

  1. Re-enroll with CAPI (cscli capi enroll) to overwrite the stored token with a fresh valid JWT
  2. Delete the corrupted apic_token row so a new one can be fetched
  3. Inspect the stored value; only a real three-part JWT is accepted

Example fix

if errors.Is(err, dbclient.ErrTokenParse) {
    // token corrupt: clear and re-enroll
    _ = client.DeleteAPICToken(ctx)
}
Defensive patterns

Strategy: try-catch

Try / catch

if errors.Is(err, dbclient.ErrTokenParse) {
    // token corrupt: delete and re-enroll/refresh
    _ = client.DeleteAPICToken(ctx)
    return refreshCAPIToken(ctx)
}

Prevention

When it happens

Trigger: The apic_token row in the DB contains a malformed/non-JWT string; claims type assertion to jwt.MapClaims fails (token.go:48).

Common situations: Manual DB edits corrupting the token, a proxy/placeholder value stored instead of a real JWT, version mismatch writing a different token format.

Understand the failure class

Related errors


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