crowdsecurity/crowdsec · warning

no header in message, skipping

Error message

no header in message, skipping

What it means

The papi (push/pull notification channel) handler unmarshals each polled event into a Message struct. If the message carries no Header object, the handler cannot route it to an operation, so it returns this error and the message is skipped.

Source

Thrown at pkg/apiserver/papi.go:139

		consoleConfig: consoleConfig,
		Logger:        logger.WithFields(log.Fields{"interval": SyncInterval.Seconds(), "source": "papi"}),
		stopChan:      make(chan struct{}),
	}

	return papi, nil
}

func (p *Papi) handleEvent(ctx context.Context, event longpollclient.Event, sync bool) error {
	logger := p.Logger.WithField("request-id", event.RequestId)
	logger.Debugf("message received: %+v", event.Data)

	message := &Message{}
	if err := json.Unmarshal([]byte(event.Data), message); err != nil {
		return fmt.Errorf("polling papi message format is not compatible: %+v: %w", event.Data, err)
	}

	if message.Header == nil {
		return errors.New("no header in message, skipping")
	}

	if message.Header.Source == nil {
		return errors.New("no source user in header message, skipping")
	}

	operationFunc, ok := operationMap[message.Header.OperationType]
	if !ok {
		return fmt.Errorf("operation '%s' unknown, continue", message.Header.OperationType)
	}

	metrics.PapiOrdersReceived.WithLabelValues(message.Header.OperationType, message.Header.OperationCmd).Inc()

	logger.Debugf("Calling operation '%s'", message.Header.OperationType)

	err := operationFunc(ctx, message, p, sync)
	if err != nil {
		return fmt.Errorf("'%s %s failed: %w", message.Header.OperationType, message.Header.OperationCmd, err)

View on GitHub (pinned to 909b515798)

Solutions

  1. Verify the sending side produces messages with the expected header object and operation_type
  2. Check for version mismatch between the two CrowdSec instances and upgrade the sender
  3. Inspect the raw event.Data logged around the error to identify the malformed source
Defensive patterns

Strategy: try-catch

Validate before calling

// sender-side: refuse to publish header-less messages
if msg.Header == nil {
    return errors.New("refusing to publish message without header")
}

Try / catch

if err := p.handleEvent(ctx, event); err != nil {
    log.WithError(err).Warnf("skipping papi event %s", event.ID)
    continue // non-fatal: bad message is skipped
}

Prevention

When it happens

Trigger: PullOnce/Pull -> handleEvent when json.Unmarshal succeeds but message.Header is nil (event.Data lacks the expected header object).

Common situations: Upstream/remote peer sends malformed or version-incompatible payloads; non-crowdsec service posting to the same channel; partial/truncated messages from the publisher.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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